mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
feat: i18n
This commit is contained in:
parent
5c4d61c45c
commit
ff3f51179b
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
class="execution-details-dialog"
|
||||
title="执行详情"
|
||||
:title="$t('components.chat.executionDetails.title')"
|
||||
v-model="dialogVisible"
|
||||
destroy-on-close
|
||||
append-to-body
|
||||
|
|
@ -56,7 +56,9 @@
|
|||
"
|
||||
>
|
||||
<div class="card-never border-r-4">
|
||||
<h5 class="p-8-12">参数输入</h5>
|
||||
<h5 class="p-8-12">
|
||||
{{ $t('components.chat.executionDetails.paramInput') }}
|
||||
</h5>
|
||||
<div class="p-8-12 border-t-dashed lighter">
|
||||
<div class="mb-8">
|
||||
<span class="color-secondary">用户问题:</span>
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ import ChatInputOperate from '@/components/ai-chat/component/chat-input-operate/
|
|||
import PrologueContent from '@/components/ai-chat/component/prologue-content/index.vue'
|
||||
import UserForm from '@/components/ai-chat/component/user-form/index.vue'
|
||||
import Control from '@/components/ai-chat/component/control/index.vue'
|
||||
import { t } from '@/locales'
|
||||
defineOptions({ name: 'AiChat' })
|
||||
const route = useRoute()
|
||||
const {
|
||||
|
|
@ -270,7 +271,7 @@ const getWrite = (chat: any, reader: any, stream: boolean) => {
|
|||
const errorWrite = (chat: any, message?: string) => {
|
||||
ChatManagement.addChatRecord(chat, 50, loading)
|
||||
ChatManagement.write(chat.id)
|
||||
ChatManagement.append(chat.id, message || '抱歉,当前正在维护,无法提供服务,请稍后再试!')
|
||||
ChatManagement.append(chat.id, message || t('components.chat.tip.error500Message'))
|
||||
ChatManagement.updateStatus(chat.id, 500)
|
||||
ChatManagement.close(chat.id)
|
||||
}
|
||||
|
|
@ -343,9 +344,9 @@ function chatMessage(chat?: any, problem?: string, re_chat?: boolean, other_para
|
|||
errorWrite(chat)
|
||||
})
|
||||
} else if (response.status === 460) {
|
||||
return Promise.reject('无法识别用户身份')
|
||||
return Promise.reject(t('components.chat.tip.errorIdentifyMessage'))
|
||||
} else if (response.status === 461) {
|
||||
return Promise.reject('抱歉,您的提问已达到最大限制,请明天再来吧!')
|
||||
return Promise.reject('components.chat.tip.errorLimitMessage')
|
||||
} else {
|
||||
nextTick(() => {
|
||||
// 将滚动条滚动到最下面
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ export default {
|
|||
debug: 'Debug',
|
||||
required: 'Required',
|
||||
noData: 'No data',
|
||||
result: 'Result',
|
||||
status: {
|
||||
label: 'Status',
|
||||
enableSuccess: 'Enable Successful',
|
||||
|
|
|
|||
|
|
@ -67,7 +67,6 @@ export default {
|
|||
paramInfo1: 'Displayed when using the function',
|
||||
paramInfo2: 'Not displayed when using the function',
|
||||
code: 'Code',
|
||||
result: 'Result'
|
||||
},
|
||||
debug: {
|
||||
run: 'Run',
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ export default {
|
|||
debug: '调试',
|
||||
required: '必填',
|
||||
noData: '暂无数据',
|
||||
result: '结果',
|
||||
status: {
|
||||
label: '状态',
|
||||
enableSuccess: '启用成功',
|
||||
|
|
|
|||
|
|
@ -11,6 +11,13 @@ export default {
|
|||
errorMessage2: '密码错误'
|
||||
},
|
||||
executionDetails: {
|
||||
title: '执行详情',
|
||||
paramInput: '参数输入',
|
||||
paramOutput: '参数输出',
|
||||
},
|
||||
tip: {
|
||||
error500Message: '抱歉,当前正在维护,无法提供服务,请稍后再试!',
|
||||
errorIdentifyMessage: '无法识别用户身份',
|
||||
errorLimitMessage:'抱歉,您的提问已达到最大限制,请明天再来吧!'
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import type { result } from 'lodash'
|
||||
|
||||
export default {
|
||||
node: '节点',
|
||||
baseNodes: '基础组件',
|
||||
baseComponent: '基础组件',
|
||||
searchBar: {
|
||||
placeholder: '按名称搜索'
|
||||
},
|
||||
|
|
@ -27,10 +29,21 @@ export default {
|
|||
onlylest: '只允许连接左边的锚点',
|
||||
applicationNodeError: '该应用不可用',
|
||||
functionNodeError: '该函数不可用',
|
||||
repeatedNodeError: '节点名称已存在!'
|
||||
repeatedNodeError: '节点名称已存在!',
|
||||
cannotCopy: '不能被复制',
|
||||
copyError: '已复制节点'
|
||||
},
|
||||
delete: {
|
||||
confirmTitle: '确定删除该节点?'
|
||||
confirmTitle: '确定删除该节点?',
|
||||
deleteMessage: '节点不允许删除'
|
||||
},
|
||||
control: {
|
||||
zoomOut: '缩小',
|
||||
zoomIn: '放大',
|
||||
fitView: '适应',
|
||||
retract: '收起全部节点',
|
||||
extend: '展开全部节点',
|
||||
beautify: '一键美化'
|
||||
},
|
||||
variable: {
|
||||
global: '全局变量',
|
||||
|
|
@ -45,5 +58,116 @@ export default {
|
|||
AND: '所有',
|
||||
OR: '任一',
|
||||
text: '连线节点执行完,执行当前节点'
|
||||
},
|
||||
validate: {
|
||||
startNodeRequired: '开始节点必填',
|
||||
startNodeOnly: '开始节点只能有一个',
|
||||
baseNodeRequired: '基本信息节点必填',
|
||||
baseNodeOnly: '基本信息节点只能有一个',
|
||||
notInWorkFlowNode: '未在流程中的节点',
|
||||
noNextNode: '不存在的下一个节点',
|
||||
nodeUnavailable: '节点不可用',
|
||||
needConnect1: '节点的',
|
||||
needConnect2: '分支需要连接',
|
||||
cannotEndNode: '节点不能当做结束节点'
|
||||
},
|
||||
nodes: {
|
||||
startNode: {
|
||||
label: '开始',
|
||||
question: '用户问题',
|
||||
currentTime: '当前时间'
|
||||
},
|
||||
baseNode: {
|
||||
label: '基本信息'
|
||||
},
|
||||
aiChatNode: {
|
||||
label: 'AI 对话',
|
||||
text: '与 AI 大模型进行对话',
|
||||
answer: 'AI 回答内容'
|
||||
},
|
||||
searchDatasetNode: {
|
||||
label: '知识库检索',
|
||||
text: '关联知识库,查找与问题相关的分段',
|
||||
paragraph_list: '检索结果的分段列表',
|
||||
is_hit_handling_method_list: '满足直接回答的分段列表',
|
||||
result: '检索结果',
|
||||
directly_return: '满足直接回答的分段内容'
|
||||
},
|
||||
questionNode: {
|
||||
label: '问题优化',
|
||||
text: '根据历史聊天记录优化完善当前问题,更利于匹配知识库分段',
|
||||
result: '问题优化结果'
|
||||
},
|
||||
conditionNode: {
|
||||
label: '判断器',
|
||||
text: '根据不同条件执行不同的节点',
|
||||
branch_name: '分支名称'
|
||||
},
|
||||
replyNode: {
|
||||
label: '指定回复',
|
||||
text: '指定回复内容,引用变量会转换为字符串进行输出',
|
||||
content: '内容'
|
||||
},
|
||||
rerankerNode: {
|
||||
label: '多路召回',
|
||||
text: '使用重排模型对多个知识库的检索结果进行二次召回',
|
||||
result_list: '重排结果列表',
|
||||
result: '重排结果'
|
||||
},
|
||||
formNode: {
|
||||
label: '表单收集',
|
||||
text: '在问答过程中用于收集用户信息,可以根据收集到表单数据执行后续流程',
|
||||
form_content_format: `你好,请先填写下面表单内容:
|
||||
{{form}}
|
||||
填写后请点击【提交】按钮进行提交。`,
|
||||
form_data: '表单全部内容'
|
||||
},
|
||||
documentExtractNode: {
|
||||
label: '文档内容提取',
|
||||
text: '提取文档中的内容',
|
||||
content: '文档内容'
|
||||
},
|
||||
imageUnderstandNode: {
|
||||
label: '图片理解',
|
||||
text: '识别出图片中的对象、场景等信息回答用户问题',
|
||||
answer: 'AI 回答内容'
|
||||
},
|
||||
imageGenerateNode: {
|
||||
label: '图片生成',
|
||||
text: '根据提供的文本内容生成图片',
|
||||
answer: 'AI 回答内容',
|
||||
image: '图片'
|
||||
},
|
||||
speechToTextNode: {
|
||||
label: '语音转文本',
|
||||
text: '将音频通过语音识别模型转换为文本'
|
||||
},
|
||||
textToSpeechNode: {
|
||||
label: '文本转语音',
|
||||
text: '将文本通过语音合成模型转换为音频'
|
||||
},
|
||||
functionNode: {
|
||||
label: '自定义函数',
|
||||
text: '通过执行自定义脚本,实现数据处理'
|
||||
},
|
||||
applicationNode: {
|
||||
label: '应用节点'
|
||||
}
|
||||
},
|
||||
compare: {
|
||||
is_null: '为空',
|
||||
is_not_null: '不为空',
|
||||
contain: '包含',
|
||||
not_contain: '不包含',
|
||||
eq: '等于',
|
||||
ge: '大于等于',
|
||||
gt: '大于',
|
||||
le: '小于等于',
|
||||
lt: '小于',
|
||||
len_eq: '长度等于',
|
||||
len_ge: '长度大于等于',
|
||||
len_gt: '长度大于',
|
||||
len_le: '长度小于等于',
|
||||
len_lt: '长度小于'
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@ export default {
|
|||
paramInfo1: '使用函数时显示',
|
||||
paramInfo2: '使用函数时不显示',
|
||||
code: '代码',
|
||||
result: '结果'
|
||||
},
|
||||
debug: {
|
||||
run: '运行',
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ export default {
|
|||
debug: '調試',
|
||||
required: '必填',
|
||||
noData: '暂无数据',
|
||||
result: '結果',
|
||||
status: {
|
||||
label: '狀態',
|
||||
enableSuccess: '啟用成功',
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@ export default {
|
|||
paramInfo1: '使用函數時顯示',
|
||||
paramInfo2: '使用函數時不顯示',
|
||||
code: '代碼',
|
||||
result: '結果'
|
||||
},
|
||||
debug: {
|
||||
run: '運行',
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
</el-input>
|
||||
</div>
|
||||
|
||||
<el-tab-pane :label="$t('views.applicationWorkflow.baseNodes')" name="base">
|
||||
<el-tab-pane :label="$t('views.applicationWorkflow.baseComponent')" name="base">
|
||||
<el-scrollbar height="400">
|
||||
<div v-if="filter_menu_nodes.length > 0">
|
||||
<template v-for="(item, index) in filter_menu_nodes" :key="index">
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@
|
|||
</el-text>
|
||||
</h4>
|
||||
<div class="flex-between border-r-4 p-8-12 mb-8 layout-bg lighter">
|
||||
<span>{{ $t('views.functionLib.functionForm.form.param.result') }} {result}</span>
|
||||
<span>{{ $t('common.result') }} {result}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,34 +1,83 @@
|
|||
<template>
|
||||
<el-card shadow="always" style="--el-card-padding: 8px 12px; --el-card-border-radius: 8px">
|
||||
<el-button link @click="zoomOut">
|
||||
<el-tooltip class="box-item" effect="dark" content="缩小" placement="top">
|
||||
<el-icon :size="16" title="缩小"><ZoomOut /></el-icon>
|
||||
<el-tooltip
|
||||
class="box-item"
|
||||
effect="dark"
|
||||
:content="$t('views.applicationWorkflow.control.zoomOut')"
|
||||
placement="top"
|
||||
>
|
||||
<el-icon :size="16" :title="$t('views.applicationWorkflow.control.zoomOut')"
|
||||
><ZoomOut
|
||||
/></el-icon>
|
||||
</el-tooltip>
|
||||
</el-button>
|
||||
<el-button link @click="zoomIn">
|
||||
<el-tooltip class="box-item" effect="dark" content="放大" placement="top">
|
||||
<el-icon :size="16" title="放大"><ZoomIn /></el-icon>
|
||||
<el-tooltip
|
||||
class="box-item"
|
||||
effect="dark"
|
||||
:content="$t('views.applicationWorkflow.control.zoomIn')"
|
||||
placement="top"
|
||||
>
|
||||
<el-icon :size="16" :title="$t('views.applicationWorkflow.control.zoomIn')"
|
||||
><ZoomIn
|
||||
/></el-icon>
|
||||
</el-tooltip>
|
||||
</el-button>
|
||||
<el-button link @click="fitView">
|
||||
<el-tooltip class="box-item" effect="dark" content="适应" placement="top">
|
||||
<AppIcon iconName="app-fitview" title="适应"></AppIcon>
|
||||
<el-tooltip
|
||||
class="box-item"
|
||||
effect="dark"
|
||||
:content="$t('views.applicationWorkflow.control.fitView')"
|
||||
placement="top"
|
||||
>
|
||||
<AppIcon
|
||||
iconName="app-fitview"
|
||||
:title="$t('views.applicationWorkflow.control.fitView')"
|
||||
></AppIcon>
|
||||
</el-tooltip>
|
||||
</el-button>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button link @click="retract">
|
||||
<el-tooltip class="box-item" effect="dark" content="收起全部节点" placement="top">
|
||||
<AppIcon style="font-size: 16px" iconName="app-retract" title="收起全部节点"></AppIcon>
|
||||
<el-tooltip
|
||||
class="box-item"
|
||||
effect="dark"
|
||||
:content="$t('views.applicationWorkflow.control.retract')"
|
||||
placement="top"
|
||||
>
|
||||
<AppIcon
|
||||
style="font-size: 16px"
|
||||
iconName="app-retract"
|
||||
:title="$t('views.applicationWorkflow.control.retract')"
|
||||
></AppIcon>
|
||||
</el-tooltip>
|
||||
</el-button>
|
||||
<el-button link @click="extend">
|
||||
<el-tooltip class="box-item" effect="dark" content="展开全部节点" placement="top">
|
||||
<AppIcon style="font-size: 16px" iconName="app-extend" title="展开全部节点"></AppIcon>
|
||||
<el-tooltip
|
||||
class="box-item"
|
||||
effect="dark"
|
||||
:content="$t('views.applicationWorkflow.control.extend')"
|
||||
placement="top"
|
||||
>
|
||||
<AppIcon
|
||||
style="font-size: 16px"
|
||||
iconName="app-extend"
|
||||
:title="$t('views.applicationWorkflow.control.extend')"
|
||||
></AppIcon>
|
||||
</el-tooltip>
|
||||
</el-button>
|
||||
<el-button link @click="layout">
|
||||
<el-tooltip class="box-item" effect="dark" content="一键美化" placement="top">
|
||||
<AppIcon style="font-size: 16px" iconName="app-beautify" title="一键美化"></AppIcon>
|
||||
<el-tooltip
|
||||
class="box-item"
|
||||
effect="dark"
|
||||
:content="$t('views.applicationWorkflow.control.beautify')"
|
||||
placement="top"
|
||||
>
|
||||
<AppIcon
|
||||
style="font-size: 16px"
|
||||
iconName="app-beautify"
|
||||
:title="$t('views.applicationWorkflow.control.beautify')"
|
||||
></AppIcon>
|
||||
</el-tooltip>
|
||||
</el-button>
|
||||
</el-card>
|
||||
|
|
|
|||
|
|
@ -8,18 +8,18 @@ export const startNode = {
|
|||
y: 720,
|
||||
properties: {
|
||||
height: 200,
|
||||
stepName: '开始',
|
||||
stepName: t('views.applicationWorkflow.nodes.startNode.label'),
|
||||
config: {
|
||||
fields: [
|
||||
{
|
||||
label: '用户问题',
|
||||
label: t('views.applicationWorkflow.nodes.startNode.question'),
|
||||
value: 'question'
|
||||
}
|
||||
],
|
||||
globalFields: [
|
||||
{
|
||||
value: 'time',
|
||||
label: '当前时间'
|
||||
label: t('views.applicationWorkflow.nodes.startNode.currentTime')
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -34,7 +34,7 @@ export const baseNode = {
|
|||
properties: {
|
||||
width: 420,
|
||||
height: 200,
|
||||
stepName: '基本信息',
|
||||
stepName: t('views.applicationWorkflow.nodes.baseNode.label'),
|
||||
input_field_list: [],
|
||||
node_data: {
|
||||
name: '',
|
||||
|
|
@ -55,15 +55,15 @@ export const baseNodes = [baseNode, startNode]
|
|||
*/
|
||||
export const aiChatNode = {
|
||||
type: WorkflowType.AiChat,
|
||||
text: '与 AI 大模型进行对话',
|
||||
label: 'AI 对话',
|
||||
text: t('views.applicationWorkflow.nodes.aiChatNode.text'),
|
||||
label: t('views.applicationWorkflow.nodes.aiChatNode.label'),
|
||||
height: 340,
|
||||
properties: {
|
||||
stepName: 'AI 对话',
|
||||
stepName: t('views.applicationWorkflow.nodes.aiChatNode.label'),
|
||||
config: {
|
||||
fields: [
|
||||
{
|
||||
label: 'AI 回答内容',
|
||||
label: t('views.applicationWorkflow.nodes.aiChatNode.answer'),
|
||||
value: 'answer'
|
||||
}
|
||||
]
|
||||
|
|
@ -75,21 +75,27 @@ export const aiChatNode = {
|
|||
*/
|
||||
export const searchDatasetNode = {
|
||||
type: WorkflowType.SearchDataset,
|
||||
text: '关联知识库,查找与问题相关的分段',
|
||||
label: '知识库检索',
|
||||
text: t('views.applicationWorkflow.nodes.searchDatasetNode.text'),
|
||||
label: t('views.applicationWorkflow.nodes.searchDatasetNode.label'),
|
||||
height: 355,
|
||||
properties: {
|
||||
stepName: '知识库检索',
|
||||
stepName: t('views.applicationWorkflow.nodes.searchDatasetNode.label'),
|
||||
config: {
|
||||
fields: [
|
||||
{ label: '检索结果的分段列表', value: 'paragraph_list' },
|
||||
{ label: '满足直接回答的分段列表', value: 'is_hit_handling_method_list' },
|
||||
{
|
||||
label: '检索结果',
|
||||
label: t('views.applicationWorkflow.nodes.searchDatasetNode.paragraph_list'),
|
||||
value: 'paragraph_list'
|
||||
},
|
||||
{
|
||||
label: t('views.applicationWorkflow.nodes.searchDatasetNode.is_hit_handling_method_list'),
|
||||
value: 'is_hit_handling_method_list'
|
||||
},
|
||||
{
|
||||
label: t('views.applicationWorkflow.nodes.searchDatasetNode.result'),
|
||||
value: 'data'
|
||||
},
|
||||
{
|
||||
label: '满足直接回答的分段内容',
|
||||
label: t('views.applicationWorkflow.nodes.searchDatasetNode.directly_return'),
|
||||
value: 'directly_return'
|
||||
}
|
||||
]
|
||||
|
|
@ -98,15 +104,15 @@ export const searchDatasetNode = {
|
|||
}
|
||||
export const questionNode = {
|
||||
type: WorkflowType.Question,
|
||||
text: '根据历史聊天记录优化完善当前问题,更利于匹配知识库分段',
|
||||
label: '问题优化',
|
||||
text: t('views.applicationWorkflow.nodes.searchDatasetNode.text'),
|
||||
label: t('views.applicationWorkflow.nodes.searchDatasetNode.label'),
|
||||
height: 345,
|
||||
properties: {
|
||||
stepName: '问题优化',
|
||||
stepName: t('views.applicationWorkflow.nodes.searchDatasetNode.label'),
|
||||
config: {
|
||||
fields: [
|
||||
{
|
||||
label: '问题优化结果',
|
||||
label: t('views.applicationWorkflow.nodes.searchDatasetNode.result'),
|
||||
value: 'answer'
|
||||
}
|
||||
]
|
||||
|
|
@ -115,16 +121,16 @@ export const questionNode = {
|
|||
}
|
||||
export const conditionNode = {
|
||||
type: WorkflowType.Condition,
|
||||
text: '根据不同条件执行不同的节点',
|
||||
label: '判断器',
|
||||
text: t('views.applicationWorkflow.nodes.conditionNode.text'),
|
||||
label: t('views.applicationWorkflow.nodes.conditionNode.label'),
|
||||
height: 175,
|
||||
properties: {
|
||||
width: 600,
|
||||
stepName: '判断器',
|
||||
stepName: t('views.applicationWorkflow.nodes.conditionNode.label'),
|
||||
config: {
|
||||
fields: [
|
||||
{
|
||||
label: '分支名称',
|
||||
label: t('views.applicationWorkflow.nodes.conditionNode.branch_name'),
|
||||
value: 'branch_name'
|
||||
}
|
||||
]
|
||||
|
|
@ -133,15 +139,15 @@ export const conditionNode = {
|
|||
}
|
||||
export const replyNode = {
|
||||
type: WorkflowType.Reply,
|
||||
text: '指定回复内容,引用变量会转换为字符串进行输出',
|
||||
label: '指定回复',
|
||||
text: t('views.applicationWorkflow.nodes.replyNode.text'),
|
||||
label: t('views.applicationWorkflow.nodes.replyNode.label'),
|
||||
height: 210,
|
||||
properties: {
|
||||
stepName: '指定回复',
|
||||
stepName: t('views.applicationWorkflow.nodes.replyNode.label'),
|
||||
config: {
|
||||
fields: [
|
||||
{
|
||||
label: '内容',
|
||||
label: t('views.applicationWorkflow.nodes.replyNode.content'),
|
||||
value: 'answer'
|
||||
}
|
||||
]
|
||||
|
|
@ -150,19 +156,19 @@ export const replyNode = {
|
|||
}
|
||||
export const rerankerNode = {
|
||||
type: WorkflowType.RrerankerNode,
|
||||
text: '使用重排模型对多个知识库的检索结果进行二次召回',
|
||||
label: '多路召回',
|
||||
text: t('views.applicationWorkflow.nodes.rerankerNode.text'),
|
||||
label: t('views.applicationWorkflow.nodes.rerankerNode.label'),
|
||||
height: 252,
|
||||
properties: {
|
||||
stepName: '多路召回',
|
||||
stepName: t('views.applicationWorkflow.nodes.rerankerNode.label'),
|
||||
config: {
|
||||
fields: [
|
||||
{
|
||||
label: '重排结果列表',
|
||||
label: t('views.applicationWorkflow.nodes.rerankerNode.result_list'),
|
||||
value: 'result_list'
|
||||
},
|
||||
{
|
||||
label: '重排结果',
|
||||
label: t('views.applicationWorkflow.nodes.rerankerNode.result'),
|
||||
value: 'result'
|
||||
}
|
||||
]
|
||||
|
|
@ -171,23 +177,21 @@ export const rerankerNode = {
|
|||
}
|
||||
export const formNode = {
|
||||
type: WorkflowType.FormNode,
|
||||
text: '在问答过程中用于收集用户信息,可以根据收集到表单数据执行后续流程',
|
||||
label: '表单收集',
|
||||
text: t('views.applicationWorkflow.nodes.formNode.text'),
|
||||
label: t('views.applicationWorkflow.nodes.formNode.label'),
|
||||
height: 252,
|
||||
properties: {
|
||||
width: 600,
|
||||
stepName: '表单收集',
|
||||
stepName: t('views.applicationWorkflow.nodes.formNode.label'),
|
||||
node_data: {
|
||||
is_result: true,
|
||||
form_field_list: [],
|
||||
form_content_format: `你好,请先填写下面表单内容:
|
||||
{{form}}
|
||||
填写后请点击【提交】按钮进行提交。`
|
||||
form_content_format: t('views.applicationWorkflow.nodes.formNode.form_content_format')
|
||||
},
|
||||
config: {
|
||||
fields: [
|
||||
{
|
||||
label: '表单全部内容',
|
||||
label: t('views.applicationWorkflow.nodes.formNode.form_data'),
|
||||
value: 'form_data'
|
||||
}
|
||||
]
|
||||
|
|
@ -196,15 +200,15 @@ export const formNode = {
|
|||
}
|
||||
export const documentExtractNode = {
|
||||
type: WorkflowType.DocumentExtractNode,
|
||||
text: '提取文档中的内容',
|
||||
label: '文档内容提取',
|
||||
text: t('views.applicationWorkflow.nodes.documentExtractNode.text'),
|
||||
label: t('views.applicationWorkflow.nodes.documentExtractNode.label'),
|
||||
height: 252,
|
||||
properties: {
|
||||
stepName: '文档内容提取',
|
||||
stepName: t('views.applicationWorkflow.nodes.documentExtractNode.label'),
|
||||
config: {
|
||||
fields: [
|
||||
{
|
||||
label: '文档内容',
|
||||
label: t('views.applicationWorkflow.nodes.documentExtractNode.content'),
|
||||
value: 'content'
|
||||
}
|
||||
]
|
||||
|
|
@ -213,15 +217,15 @@ export const documentExtractNode = {
|
|||
}
|
||||
export const imageUnderstandNode = {
|
||||
type: WorkflowType.ImageUnderstandNode,
|
||||
text: '识别出图片中的对象、场景等信息回答用户问题',
|
||||
label: '图片理解',
|
||||
text: t('views.applicationWorkflow.nodes.imageUnderstandNode.text'),
|
||||
label: t('views.applicationWorkflow.nodes.imageUnderstandNode.label'),
|
||||
height: 252,
|
||||
properties: {
|
||||
stepName: '图片理解',
|
||||
stepName: t('views.applicationWorkflow.nodes.imageUnderstandNode.label'),
|
||||
config: {
|
||||
fields: [
|
||||
{
|
||||
label: 'AI 回答内容',
|
||||
label: t('views.applicationWorkflow.nodes.imageUnderstandNode.answer'),
|
||||
value: 'answer'
|
||||
}
|
||||
]
|
||||
|
|
@ -231,19 +235,19 @@ export const imageUnderstandNode = {
|
|||
|
||||
export const imageGenerateNode = {
|
||||
type: WorkflowType.ImageGenerateNode,
|
||||
text: '根据提供的文本内容生成图片',
|
||||
label: '图片生成',
|
||||
text: t('views.applicationWorkflow.nodes.imageGenerateNode.text'),
|
||||
label: t('views.applicationWorkflow.nodes.imageGenerateNode.label'),
|
||||
height: 252,
|
||||
properties: {
|
||||
stepName: '图片生成',
|
||||
stepName: t('views.applicationWorkflow.nodes.imageGenerateNode.label'),
|
||||
config: {
|
||||
fields: [
|
||||
{
|
||||
label: 'AI 回答内容',
|
||||
label: t('views.applicationWorkflow.nodes.imageGenerateNode.answer'),
|
||||
value: 'answer'
|
||||
},
|
||||
{
|
||||
label: '图片',
|
||||
label: t('views.applicationWorkflow.nodes.imageGenerateNode.image'),
|
||||
value: 'image'
|
||||
}
|
||||
]
|
||||
|
|
@ -253,15 +257,15 @@ export const imageGenerateNode = {
|
|||
|
||||
export const speechToTextNode = {
|
||||
type: WorkflowType.SpeechToTextNode,
|
||||
text: '将音频通过语音识别模型转换为文本',
|
||||
label: '语音转文本',
|
||||
text: t('views.applicationWorkflow.nodes.speechToTextNode.text'),
|
||||
label: t('views.applicationWorkflow.nodes.speechToTextNode.label'),
|
||||
height: 252,
|
||||
properties: {
|
||||
stepName: '语音转文本',
|
||||
stepName: t('views.applicationWorkflow.nodes.speechToTextNode.label'),
|
||||
config: {
|
||||
fields: [
|
||||
{
|
||||
label: '结果',
|
||||
label: t('common.result'),
|
||||
value: 'result'
|
||||
}
|
||||
]
|
||||
|
|
@ -270,15 +274,15 @@ export const speechToTextNode = {
|
|||
}
|
||||
export const textToSpeechNode = {
|
||||
type: WorkflowType.TextToSpeechNode,
|
||||
text: '将文本通过语音合成模型转换为音频',
|
||||
label: '文本转语音',
|
||||
text: t('views.applicationWorkflow.nodes.textToSpeechNode.text'),
|
||||
label: t('views.applicationWorkflow.nodes.textToSpeechNode.label'),
|
||||
height: 252,
|
||||
properties: {
|
||||
stepName: '文本转语音',
|
||||
stepName: t('views.applicationWorkflow.nodes.textToSpeechNode.label'),
|
||||
config: {
|
||||
fields: [
|
||||
{
|
||||
label: '结果',
|
||||
label: t('common.result'),
|
||||
value: 'result'
|
||||
}
|
||||
]
|
||||
|
|
@ -305,15 +309,15 @@ export const menuNodes = [
|
|||
*/
|
||||
export const functionNode = {
|
||||
type: WorkflowType.FunctionLibCustom,
|
||||
text: '通过执行自定义脚本,实现数据处理',
|
||||
label: '自定义函数',
|
||||
text: t('views.applicationWorkflow.nodes.functionNode.text'),
|
||||
label: t('views.applicationWorkflow.nodes.functionNode.label'),
|
||||
height: 260,
|
||||
properties: {
|
||||
stepName: '自定义函数',
|
||||
stepName: t('views.applicationWorkflow.nodes.functionNode.label'),
|
||||
config: {
|
||||
fields: [
|
||||
{
|
||||
label: '结果',
|
||||
label: t('common.result'),
|
||||
value: 'result'
|
||||
}
|
||||
]
|
||||
|
|
@ -322,15 +326,15 @@ export const functionNode = {
|
|||
}
|
||||
export const functionLibNode = {
|
||||
type: WorkflowType.FunctionLib,
|
||||
text: '通过执行自定义脚本,实现数据处理',
|
||||
label: '自定义函数',
|
||||
text: t('views.applicationWorkflow.nodes.functionNode.text'),
|
||||
label: t('views.applicationWorkflow.nodes.functionNode.label'),
|
||||
height: 170,
|
||||
properties: {
|
||||
stepName: '自定义函数',
|
||||
stepName: t('views.applicationWorkflow.nodes.functionNode.label'),
|
||||
config: {
|
||||
fields: [
|
||||
{
|
||||
label: '结果',
|
||||
label: t('common.result'),
|
||||
value: 'result'
|
||||
}
|
||||
]
|
||||
|
|
@ -340,15 +344,15 @@ export const functionLibNode = {
|
|||
|
||||
export const applicationNode = {
|
||||
type: WorkflowType.Application,
|
||||
text: '应用节点',
|
||||
label: '应用节点',
|
||||
text: t('views.applicationWorkflow.nodes.applicationNode.label'),
|
||||
label: t('views.applicationWorkflow.nodes.applicationNode.label'),
|
||||
height: 260,
|
||||
properties: {
|
||||
stepName: '应用节点',
|
||||
stepName: t('views.applicationWorkflow.nodes.applicationNode.label'),
|
||||
config: {
|
||||
fields: [
|
||||
{
|
||||
label: '结果',
|
||||
label: t('common.result'),
|
||||
value: 'result'
|
||||
}
|
||||
]
|
||||
|
|
@ -357,20 +361,20 @@ export const applicationNode = {
|
|||
}
|
||||
|
||||
export const compareList = [
|
||||
{ value: 'is_null', label: '为空' },
|
||||
{ value: 'is_not_null', label: '不为空' },
|
||||
{ value: 'contain', label: '包含' },
|
||||
{ value: 'not_contain', label: '不包含' },
|
||||
{ value: 'eq', label: '等于' },
|
||||
{ value: 'ge', label: '大于等于' },
|
||||
{ value: 'gt', label: '大于' },
|
||||
{ value: 'le', label: '小于等于' },
|
||||
{ value: 'lt', label: '小于' },
|
||||
{ value: 'len_eq', label: '长度等于' },
|
||||
{ value: 'len_ge', label: '长度大于等于' },
|
||||
{ value: 'len_gt', label: '长度大于' },
|
||||
{ value: 'len_le', label: '长度小于等于' },
|
||||
{ value: 'len_lt', label: '长度小于' }
|
||||
{ value: 'is_null', label: t('views.applicationWorkflow.compare.is_null') },
|
||||
{ value: 'is_not_null', label: t('views.applicationWorkflow.compare.is_not_null') },
|
||||
{ value: 'contain', label: t('views.applicationWorkflow.compare.contain') },
|
||||
{ value: 'not_contain', label: t('views.applicationWorkflow.compare.not_contain') },
|
||||
{ value: 'eq', label: t('views.applicationWorkflow.compare.eq') },
|
||||
{ value: 'ge', label: t('views.applicationWorkflow.compare.ge') },
|
||||
{ value: 'gt', label:t('views.applicationWorkflow.compare.gt') },
|
||||
{ value: 'le', label: t('views.applicationWorkflow.compare.le') },
|
||||
{ value: 'lt', label: t('views.applicationWorkflow.compare.lt') },
|
||||
{ value: 'len_eq', label: t('views.applicationWorkflow.compare.len_eq')},
|
||||
{ value: 'len_ge', label: t('views.applicationWorkflow.compare.len_ge') },
|
||||
{ value: 'len_gt', label:t('views.applicationWorkflow.compare.len_gt') },
|
||||
{ value: 'len_le', label: t('views.applicationWorkflow.compare.len_le') },
|
||||
{ value: 'len_lt', label: t('views.applicationWorkflow.compare.len_lt') }
|
||||
]
|
||||
|
||||
export const nodeDict: any = {
|
||||
|
|
|
|||
|
|
@ -60,13 +60,13 @@ export function initDefaultShortcut(lf: LogicFlow, graph: GraphModel) {
|
|||
(node: any) => node.type === WorkflowType.Start || node.type === WorkflowType.Base
|
||||
)
|
||||
if (base_nodes.length > 0) {
|
||||
MsgError(base_nodes[0]?.properties?.stepName + '不能被复制')
|
||||
MsgError(base_nodes[0]?.properties?.stepName + t('views.applicationWorkflow.tip.cannotCopy'))
|
||||
return
|
||||
}
|
||||
selected = elements
|
||||
selected.nodes.forEach((node: any) => translationNodeData(node, TRANSLATION_DISTANCE))
|
||||
selected.edges.forEach((edge: any) => translationEdgeData(edge, TRANSLATION_DISTANCE))
|
||||
MsgSuccess('已复制节点')
|
||||
MsgSuccess(t('views.applicationWorkflow.tip.copyError'))
|
||||
return false
|
||||
}
|
||||
const paste_node = () => {
|
||||
|
|
@ -96,7 +96,7 @@ export function initDefaultShortcut(lf: LogicFlow, graph: GraphModel) {
|
|||
}
|
||||
const nodes = elements.nodes.filter((node) => ['start-node', 'base-node'].includes(node.type))
|
||||
if (nodes.length > 0) {
|
||||
MsgError(`${nodes[0].properties?.stepName}节点不允许删除`)
|
||||
MsgError(`${nodes[0].properties?.stepName}${t('views.applicationWorkflow.delete.deleteMessage')}`)
|
||||
return
|
||||
}
|
||||
MsgConfirm(t('common.tip'), t('views.applicationWorkflow.delete.confirmTitle'), {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { WorkflowType } from '@/enums/workflow'
|
||||
import { t } from '@/locales'
|
||||
|
||||
const end_nodes: Array<string> = [
|
||||
WorkflowType.AiChat,
|
||||
|
|
@ -26,9 +27,9 @@ export class WorkFlowInstance {
|
|||
private is_valid_start_node() {
|
||||
const start_node_list = this.nodes.filter((item) => item.id === WorkflowType.Start)
|
||||
if (start_node_list.length == 0) {
|
||||
throw '开始节点必填'
|
||||
throw t('views.applicationWorkflow.validate.startNodeRequired')
|
||||
} else if (start_node_list.length > 1) {
|
||||
throw '开始节点只能有一个'
|
||||
throw t('views.applicationWorkflow.validate.startNodeOnly')
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
|
@ -37,9 +38,9 @@ export class WorkFlowInstance {
|
|||
private is_valid_base_node() {
|
||||
const start_node_list = this.nodes.filter((item) => item.id === WorkflowType.Base)
|
||||
if (start_node_list.length == 0) {
|
||||
throw '基本信息节点必填'
|
||||
throw t('views.applicationWorkflow.validate.baseNodeRequired')
|
||||
} else if (start_node_list.length > 1) {
|
||||
throw '基本信息节点只能有一个'
|
||||
throw t('views.applicationWorkflow.validate.baseNodeOnly')
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
|
@ -91,7 +92,7 @@ export class WorkFlowInstance {
|
|||
.filter((node: any) => node.id !== WorkflowType.Start && node.id !== WorkflowType.Base)
|
||||
.filter((node) => !this.workFlowNodes.includes(node))
|
||||
if (notInWorkFlowNodes.length > 0) {
|
||||
throw `未在流程中的节点:${notInWorkFlowNodes.map((node) => node.properties.stepName).join(',')}`
|
||||
throw `${t('views.applicationWorkflow.validate.notInWorkFlowNode')}:${notInWorkFlowNodes.map((node) => node.properties.stepName).join(',')}`
|
||||
}
|
||||
this.workFlowNodes = []
|
||||
}
|
||||
|
|
@ -106,7 +107,7 @@ export class WorkFlowInstance {
|
|||
.map((edge) => this.nodes.filter((node) => node.id == edge.targetNodeId))
|
||||
.reduce((x, y) => [...x, ...y], [])
|
||||
if (node_list.length == 0 && !end_nodes.includes(node.type)) {
|
||||
throw '不存在的下一个节点'
|
||||
throw t('views.applicationWorkflow.validate.noNextNode')
|
||||
}
|
||||
return node_list
|
||||
}
|
||||
|
|
@ -114,7 +115,7 @@ export class WorkFlowInstance {
|
|||
for (const node of this.nodes) {
|
||||
if (node.type !== WorkflowType.Base && node.type !== WorkflowType.Start) {
|
||||
if (!this.edges.some((edge) => edge.targetNodeId === node.id)) {
|
||||
throw `未在流程中的节点:${node.properties.stepName}`
|
||||
throw `${t('views.applicationWorkflow.validate.notInWorkFlowNode')}:${node.properties.stepName}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -125,7 +126,7 @@ export class WorkFlowInstance {
|
|||
*/
|
||||
private is_valid_node(node: any) {
|
||||
if (node.properties.status && node.properties.status === 500) {
|
||||
throw `${node.properties.stepName} 节点不可用`
|
||||
throw `${node.properties.stepName} ${t('views.applicationWorkflow.validate.nodeUnavailable')}`
|
||||
}
|
||||
if (node.type === WorkflowType.Condition) {
|
||||
const branch_list = node.properties.node_data.branch
|
||||
|
|
@ -133,17 +134,17 @@ export class WorkFlowInstance {
|
|||
const source_anchor_id = `${node.id}_${branch.id}_right`
|
||||
const edge_list = this.edges.filter((edge) => edge.sourceAnchorId == source_anchor_id)
|
||||
if (edge_list.length == 0) {
|
||||
throw `${node.properties.stepName} 节点的${branch.type}分支需要连接`
|
||||
throw `${node.properties.stepName} ${t('views.applicationWorkflow.validate.needConnect1')}${branch.type}${t('views.applicationWorkflow.validate.needConnect2')}`
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const edge_list = this.edges.filter((edge) => edge.sourceNodeId == node.id)
|
||||
if (edge_list.length == 0 && !end_nodes.includes(node.type)) {
|
||||
throw `${node.properties.stepName} 节点不能当做结束节点`
|
||||
throw `${node.properties.stepName} ${t('views.applicationWorkflow.validate.cannotEndNode')}`
|
||||
}
|
||||
}
|
||||
if (node.properties.status && node.properties.status !== 200) {
|
||||
throw `${node.properties.stepName} 节点不可用`
|
||||
throw `${node.properties.stepName} ${t('views.applicationWorkflow.validate.nodeUnavailable')}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@
|
|||
<div class="flex-between">
|
||||
<div>历史聊天记录</div>
|
||||
<el-select v-model="chat_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-select>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<NodeContainer :nodeModel="nodeModel">
|
||||
<h5 class="title-decoration-1 mb-8">全局变量</h5>
|
||||
<h5 class="title-decoration-1 mb-8">{{ $t('views.applicationWorkflow.variable.global') }}</h5>
|
||||
<div
|
||||
v-for="(item, index) in nodeModel.properties.config.globalFields"
|
||||
:key="index"
|
||||
|
|
@ -9,10 +9,19 @@
|
|||
@mouseleave="showicon = false"
|
||||
>
|
||||
<span>{{ item.label }} {{ '{' + item.value + '}' }}</span>
|
||||
<el-tooltip effect="dark" :content="$t('views.applicationWorkflow.setting.copyParam')" placement="top" v-if="showicon === true">
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
content="$t('views.applicationWorkflow.setting.copyParam')"
|
||||
placement="top"
|
||||
v-if="showicon === true"
|
||||
>
|
||||
<el-button
|
||||
link
|
||||
@click="copyClick('{{' + '全局变量.' + item.value + '}}')"
|
||||
@click="
|
||||
copyClick(
|
||||
`{{${$t('views.applicationWorkflow.variable.global')}.${item.value}}}`
|
||||
)
|
||||
"
|
||||
style="padding: 0"
|
||||
>
|
||||
<AppIcon iconName="app-copy"></AppIcon>
|
||||
|
|
@ -69,7 +78,13 @@ const refreshFileUploadConfig = () => {
|
|||
.map((v: any) => cloneDeep(v.properties.node_data.file_upload_setting))
|
||||
.filter((v: any) => v)
|
||||
|
||||
fields = fields.filter((item: any) => item.value !== 'image' && item.value !== 'document' && item.value !== 'audio' && item.value !== 'video')
|
||||
fields = fields.filter(
|
||||
(item: any) =>
|
||||
item.value !== 'image' &&
|
||||
item.value !== 'document' &&
|
||||
item.value !== 'audio' &&
|
||||
item.value !== 'video'
|
||||
)
|
||||
|
||||
if (form_data.length === 0) {
|
||||
set(props.nodeModel.properties.config, 'fields', fields)
|
||||
|
|
|
|||
Loading…
Reference in New Issue