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

View File

@ -19,7 +19,7 @@
<el-form-item label="优化后问题"> <el-form-item label="优化后问题">
<el-input v-model="detail.padding_problem_text" disabled /> <el-input v-model="detail.padding_problem_text" disabled />
</el-form-item> </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"> <div v-if="detail.paragraph_list.length > 0" class="w-full">
<template v-for="(item, index) in detail.paragraph_list" :key="index"> <template v-for="(item, index) in detail.paragraph_list" :key="index">
<ParagraphCard :data="item" :index="index" /> <ParagraphCard :data="item" :index="index" />

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -20,7 +20,7 @@
</el-button> </el-button>
</div> </div>
<!-- Codemirror 弹出层 --> <!-- 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 <Codemirror
v-model="cloneContent" v-model="cloneContent"
:extensions="extensions" :extensions="extensions"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,7 +4,7 @@
<template #sub-title> <template #sub-title>
<div class="mt-8"> <div class="mt-8">
<span class="bold">{{ data?.document_list.length || 0 }}</span> <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" /> <el-divider direction="vertical" />
<span class="bold">{{ paragraph_count || 0 }}</span> <span class="bold">{{ paragraph_count || 0 }}</span>
<el-text type="info" class="ml-4">{{ <el-text type="info" class="ml-4">{{

View File

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

View File

@ -1,5 +1,5 @@
<template> <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="main-calc-height">
<div class="p-24"> <div class="p-24">
<div class="flex-between"> <div class="flex-between">

View File

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

View File

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

View File

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

View File

@ -186,7 +186,9 @@ export const formNode = {
node_data: { node_data: {
is_result: true, is_result: true,
form_field_list: [], 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: { config: {
fields: [ fields: [

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
<template> <template>
<el-dialog <el-dialog
title="文件上传设置" :title="$t('views.applicationWorkflow.nodes.baseNode.FileUploadSetting.title')"
v-model="dialogVisible" v-model="dialogVisible"
:close-on-click-modal="false" :close-on-click-modal="false"
:close-on-press-escape="false" :close-on-press-escape="false"
@ -15,7 +15,7 @@
:model="form_data" :model="form_data"
require-asterisk-position="right" require-asterisk-position="right"
> >
<el-form-item label="单次上传最多文件数"> <el-form-item :label="$t('views.applicationWorkflow.nodes.baseNode.FileUploadSetting.maxFiles')">
<el-slider <el-slider
v-model="form_data.maxFiles" v-model="form_data.maxFiles"
show-input show-input
@ -24,7 +24,7 @@
:max="10" :max="10"
/> />
</el-form-item> </el-form-item>
<el-form-item label="每个文件最大MB"> <el-form-item :label="$t('views.applicationWorkflow.nodes.baseNode.FileUploadSetting.fileLimit')">
<el-slider <el-slider
v-model="form_data.fileLimit" v-model="form_data.fileLimit"
show-input show-input
@ -33,7 +33,7 @@
:max="100" :max="100"
/> />
</el-form-item> </el-form-item>
<el-form-item label="上传的文件类型"> <el-form-item :label="$t('views.applicationWorkflow.nodes.baseNode.FileUploadSetting.fileUploadType.label')">
<el-card <el-card
shadow="hover" shadow="hover"
class="card-checkbox cursor w-full mb-8" class="card-checkbox cursor w-full mb-8"
@ -45,8 +45,10 @@
<div class="flex align-center"> <div class="flex align-center">
<img class="mr-12" src="@/assets/icon_file-doc.svg" alt="" /> <img class="mr-12" src="@/assets/icon_file-doc.svg" alt="" />
<div> <div>
<p class="line-height-22 mt-4">文档TXTMDDOCXHTMLCSVXLSXXLSPDF</p> <p class="line-height-22 mt-4">
<el-text class="color-secondary">需要使用文档内容提取节点解析文档内容</el-text> {{ $t('common.fileUpload.document') }}TXTMDDOCXHTMLCSVXLSXXLSPDF
</p>
<el-text class="color-secondary">{{$t('views.applicationWorkflow.nodes.baseNode.FileUploadSetting.fileUploadType.documentText')}}</el-text>
</div> </div>
</div> </div>
<el-checkbox <el-checkbox
@ -66,8 +68,10 @@
<div class="flex align-center"> <div class="flex align-center">
<img class="mr-12" src="@/assets/icon_file-image.svg" alt="" /> <img class="mr-12" src="@/assets/icon_file-image.svg" alt="" />
<div> <div>
<p class="line-height-22 mt-4">图片JPGJPEGPNGGIF</p> <p class="line-height-22 mt-4">
<el-text class="color-secondary">需要使用图片理解节点解析图片内容</el-text> {{ $t('common.fileUpload.image') }}JPGJPEGPNGGIF
</p>
<el-text class="color-secondary">{{$t('views.applicationWorkflow.nodes.baseNode.FileUploadSetting.fileUploadType.imageText')}}</el-text>
</div> </div>
</div> </div>
<el-checkbox v-model="form_data.image" @change="form_data.image = !form_data.image" /> <el-checkbox v-model="form_data.image" @change="form_data.image = !form_data.image" />
@ -85,8 +89,8 @@
<div class="flex align-center"> <div class="flex align-center">
<img class="mr-12" src="@/assets/icon_file-audio.svg" alt="" /> <img class="mr-12" src="@/assets/icon_file-audio.svg" alt="" />
<div> <div>
<p class="line-height-22 mt-4">音频MP3WAVOGGACC</p> <p class="line-height-22 mt-4">{{ $t('common.fileUpload.audio') }}MP3WAVOGGACC</p>
<el-text class="color-secondary">需要使用语音转文本节点解析音频内容</el-text> <el-text class="color-secondary">{{$t('views.applicationWorkflow.nodes.baseNode.FileUploadSetting.fileUploadType.audioText')}}</el-text>
</div> </div>
</div> </div>
<el-checkbox v-model="form_data.audio" @change="form_data.audio = !form_data.audio" /> <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 DynamicsFormConstructor from '@/components/dynamics-form/constructor/index.vue'
import type { FormField } from '@/components/dynamics-form/type' import type { FormField } from '@/components/dynamics-form/type'
import _ from 'lodash' import _ from 'lodash'
import { t } from '@/locales'
const emit = defineEmits(['refresh']) const emit = defineEmits(['refresh'])
const DynamicsFormConstructorRef = ref() const DynamicsFormConstructorRef = ref()
@ -121,11 +122,11 @@ const currentRow = computed(() => {
}) })
const currentIndex = ref(null) const currentIndex = ref(null)
const inputTypeList = ref([ const inputTypeList = ref([
{ label: '文本框', value: 'TextInputConstructor' }, { label: t('components.dynamicsForm.input_type_list.TextInput'), value: 'TextInputConstructor' },
{ label: '单选框', value: 'SingleSelectConstructor' }, { label: t('components.dynamicsForm.input_type_list.SingleSelect'), value: 'SingleSelectConstructor' },
{ label: '多选框', value: 'MultiSelectConstructor' }, { label: t('components.dynamicsForm.input_type_list.MultiSelect'), value: 'MultiSelectConstructor' },
{ label: '选项卡', value: 'RadioCardConstructor' }, { label: t('components.dynamicsForm.input_type_list.RadioCard'), value: 'RadioCardConstructor' },
{ label: '日期', value: 'DatePickerConstructor' } { label: t('components.dynamicsForm.input_type_list.DatePicker'), value: 'DatePickerConstructor' }
]) ])
const dialogVisible = ref<boolean>(false) const dialogVisible = ref<boolean>(false)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -18,8 +18,14 @@
<el-form-item> <el-form-item>
<template #label> <template #label>
<div class="flex align-center"> <div class="flex align-center">
<span class="mr-4">Score 高于</span> <span class="mr-4"
<el-tooltip effect="dark" content="Score越高相关性越强。" placement="right"> >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> <AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip> </el-tooltip>
</div> </div>

View File

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

View File

@ -1,6 +1,6 @@
<template> <template>
<NodeContainer :nodeModel="nodeModel"> <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-card shadow="never" class="card-never">
<el-form <el-form
@submit.prevent @submit.prevent
@ -10,10 +10,10 @@
label-width="auto" label-width="auto"
ref="DatasetNodeFormRef" ref="DatasetNodeFormRef"
> >
<el-form-item label="选择知识库"> <el-form-item :label="$t('views.log.selectDataset')">
<template #label> <template #label>
<div class="flex-between"> <div class="flex-between">
<span>选择知识库</span> <span>{{ $t('views.log.selectDataset') }}</span>
<el-button type="primary" link @click="openDatasetDialog"> <el-button type="primary" link @click="openDatasetDialog">
<el-icon><Plus /></el-icon> <el-icon><Plus /></el-icon>
</el-button> </el-button>
@ -21,7 +21,7 @@
</template> </template>
<div class="w-full"> <div class="w-full">
<el-text type="info" v-if="form_data.dataset_id_list?.length === 0"> <el-text type="info" v-if="form_data.dataset_id_list?.length === 0">
关联的知识库展示在这里 {{ $t('views.applicationWorkflow.nodes.searchDatasetNode.selectDatasetText') }}
</el-text> </el-text>
<template v-for="(item, index) in form_data.dataset_id_list" :key="index" v-else> <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"> <div class="flex-between border border-r-4 white-bg mb-4" style="padding: 5px 8px">
@ -50,10 +50,10 @@
</template> </template>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="检索参数"> <el-form-item :label="$t('views.applicationWorkflow.nodes.searchDatasetNode.searchParam')">
<template #label> <template #label>
<div class="flex-between"> <div class="flex-between">
<span>检索参数</span> <span>{{ $t('views.applicationWorkflow.nodes.searchDatasetNode.searchParam') }}</span>
<el-button type="primary" link @click="openParamSettingDialog"> <el-button type="primary" link @click="openParamSettingDialog">
<el-icon><Setting /></el-icon> <el-icon><Setting /></el-icon>
</el-button> </el-button>
@ -61,19 +61,27 @@
</template> </template>
<div class="w-full"> <div class="w-full">
<el-row> <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"> <el-col :span="12" class="lighter">
{{ {{
SearchMode[form_data.dataset_setting.search_mode as keyof typeof SearchMode] SearchMode[form_data.dataset_setting.search_mode as keyof typeof SearchMode]
}}</el-col }}</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"> <el-col :span="12" class="lighter">
{{ form_data.dataset_setting.similarity?.toFixed(3) }}</el-col {{ 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="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"> <el-col :span="12" class="lighter">
{{ form_data.dataset_setting.max_paragraph_char_number }}</el-col {{ form_data.dataset_setting.max_paragraph_char_number }}</el-col
> >
@ -81,10 +89,10 @@
</div> </div>
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="检索问题" :label="$t('views.applicationWorkflow.nodes.searchDatasetNode.searchQuestion.label')"
prop="question_reference_address" prop="question_reference_address"
:rules="{ :rules="{
message: '请选择检索问题', message: $t('views.applicationWorkflow.nodes.searchDatasetNode.searchQuestion.requiredMessage'),
trigger: 'blur', trigger: 'blur',
required: true required: true
}" }"
@ -93,7 +101,7 @@
ref="nodeCascaderRef" ref="nodeCascaderRef"
:nodeModel="nodeModel" :nodeModel="nodeModel"
class="w-full" class="w-full"
placeholder="请选择检索问题" :placeholder="$t('views.applicationWorkflow.nodes.searchDatasetNode.searchQuestion.placeholder')"
v-model="form_data.question_reference_address" v-model="form_data.question_reference_address"
/> />
</el-form-item> </el-form-item>

View File

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

View File

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

View File

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