feat: Create workflow applications that support template selection
This commit is contained in:
parent
6b72611b72
commit
4367b1c650
@ -46,6 +46,10 @@ export default {
|
|||||||
simplePlaceholder: 'Suitable for beginners to create assistant.',
|
simplePlaceholder: 'Suitable for beginners to create assistant.',
|
||||||
workflowPlaceholder: 'Suitable for advanced users to customize the workflow of assistant'
|
workflowPlaceholder: 'Suitable for advanced users to customize the workflow of assistant'
|
||||||
},
|
},
|
||||||
|
appTemplate: {
|
||||||
|
blankApp: 'Blank APP',
|
||||||
|
assistantApp: 'Knowledge Assistant'
|
||||||
|
},
|
||||||
aiModel: {
|
aiModel: {
|
||||||
label: 'AI Model',
|
label: 'AI Model',
|
||||||
placeholder: 'Please select an AI model'
|
placeholder: 'Please select an AI model'
|
||||||
@ -110,7 +114,7 @@ export default {
|
|||||||
reasoningContent: {
|
reasoningContent: {
|
||||||
label: 'Output Thinking',
|
label: 'Output Thinking',
|
||||||
tooltip:
|
tooltip:
|
||||||
'Please set the thinking label based on the model\'s return, and the content in the middle of the label will be recognized as the thinking process.',
|
"Please set the thinking label based on the model's return, and the content in the middle of the label will be recognized as the thinking process.",
|
||||||
start: 'Start',
|
start: 'Start',
|
||||||
end: 'End'
|
end: 'End'
|
||||||
}
|
}
|
||||||
@ -211,7 +215,7 @@ export default {
|
|||||||
slackSetting: {
|
slackSetting: {
|
||||||
title: 'Slack Configuration',
|
title: 'Slack Configuration',
|
||||||
signingSecretPlaceholder: 'Please enter signing secret',
|
signingSecretPlaceholder: 'Please enter signing secret',
|
||||||
botUserTokenPlaceholder: 'Please enter bot user token',
|
botUserTokenPlaceholder: 'Please enter bot user token'
|
||||||
},
|
},
|
||||||
copyUrl: 'Copy the link and fill it in'
|
copyUrl: 'Copy the link and fill it in'
|
||||||
},
|
},
|
||||||
|
|||||||
@ -41,6 +41,10 @@ export default {
|
|||||||
simplePlaceholder: '适合新手创建小助手',
|
simplePlaceholder: '适合新手创建小助手',
|
||||||
workflowPlaceholder: '适合高级用户自定义小助手的工作流'
|
workflowPlaceholder: '适合高级用户自定义小助手的工作流'
|
||||||
},
|
},
|
||||||
|
appTemplate: {
|
||||||
|
blankApp: '空白应用',
|
||||||
|
assistantApp: '知识库问答助手'
|
||||||
|
},
|
||||||
aiModel: {
|
aiModel: {
|
||||||
label: 'AI 模型',
|
label: 'AI 模型',
|
||||||
placeholder: '请选择 AI 模型'
|
placeholder: '请选择 AI 模型'
|
||||||
@ -198,7 +202,7 @@ export default {
|
|||||||
slackSetting: {
|
slackSetting: {
|
||||||
title: 'Slack 应用配置',
|
title: 'Slack 应用配置',
|
||||||
signingSecretPlaceholder: '请输入 Signing Secret',
|
signingSecretPlaceholder: '请输入 Signing Secret',
|
||||||
botUserTokenPlaceholder: '请输入 Bot User Token',
|
botUserTokenPlaceholder: '请输入 Bot User Token'
|
||||||
},
|
},
|
||||||
copyUrl: '复制链接填入到'
|
copyUrl: '复制链接填入到'
|
||||||
},
|
},
|
||||||
|
|||||||
@ -41,6 +41,10 @@ export default {
|
|||||||
simplePlaceholder: '適合新手建立小助手',
|
simplePlaceholder: '適合新手建立小助手',
|
||||||
workflowPlaceholder: '適合高階用戶自訂小助手的工作流程'
|
workflowPlaceholder: '適合高階用戶自訂小助手的工作流程'
|
||||||
},
|
},
|
||||||
|
appTemplate: {
|
||||||
|
blankApp: '空白應用',
|
||||||
|
assistantApp: '知識庫問答助手'
|
||||||
|
},
|
||||||
aiModel: {
|
aiModel: {
|
||||||
label: 'AI 模型',
|
label: 'AI 模型',
|
||||||
placeholder: '請選擇 AI 模型'
|
placeholder: '請選擇 AI 模型'
|
||||||
|
|||||||
@ -38,11 +38,7 @@
|
|||||||
<el-radio-group v-model="applicationForm.type" class="card__radio">
|
<el-radio-group v-model="applicationForm.type" class="card__radio">
|
||||||
<el-row :gutter="16">
|
<el-row :gutter="16">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-card
|
<el-card shadow="never" :class="applicationForm.type === 'SIMPLE' ? 'active' : ''">
|
||||||
shadow="never"
|
|
||||||
class="mb-16"
|
|
||||||
:class="applicationForm.type === 'SIMPLE' ? 'active' : ''"
|
|
||||||
>
|
|
||||||
<el-radio value="SIMPLE" size="large">
|
<el-radio value="SIMPLE" size="large">
|
||||||
<p class="mb-4">{{ $t('views.application.simple') }}</p>
|
<p class="mb-4">{{ $t('views.application.simple') }}</p>
|
||||||
<el-text type="info">{{
|
<el-text type="info">{{
|
||||||
@ -52,11 +48,7 @@
|
|||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-card
|
<el-card shadow="never" :class="isWorkFlow(applicationForm.type) ? 'active' : ''">
|
||||||
shadow="never"
|
|
||||||
class="mb-16"
|
|
||||||
:class="isWorkFlow(applicationForm.type) ? 'active' : ''"
|
|
||||||
>
|
|
||||||
<el-radio value="WORK_FLOW" size="large">
|
<el-radio value="WORK_FLOW" size="large">
|
||||||
<p class="mb-4">{{ $t('views.application.workflow') }}</p>
|
<p class="mb-4">{{ $t('views.application.workflow') }}</p>
|
||||||
<el-text type="info">{{
|
<el-text type="info">{{
|
||||||
@ -68,6 +60,35 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item
|
||||||
|
:label="$t('views.document.upload.template')"
|
||||||
|
v-if="applicationForm.type === 'WORK_FLOW'"
|
||||||
|
>
|
||||||
|
<div class="w-full">
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-card
|
||||||
|
class="radio-card cursor"
|
||||||
|
shadow="never"
|
||||||
|
@click="selectedType('blank')"
|
||||||
|
:class="appTemplate === 'blank' ? 'active' : ''"
|
||||||
|
>
|
||||||
|
{{ $t('views.application.applicationForm.form.appTemplate.blankApp') }}
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-card
|
||||||
|
class="radio-card cursor"
|
||||||
|
shadow="never"
|
||||||
|
:class="appTemplate === 'assistant' ? 'active' : ''"
|
||||||
|
@click="selectedType('assistant')"
|
||||||
|
>
|
||||||
|
{{ $t('views.application.applicationForm.form.appTemplate.assistantApp') }}
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
@ -89,6 +110,7 @@ import type { FormInstance, FormRules } from 'element-plus'
|
|||||||
import applicationApi from '@/api/application'
|
import applicationApi from '@/api/application'
|
||||||
import { MsgSuccess, MsgAlert } from '@/utils/message'
|
import { MsgSuccess, MsgAlert } from '@/utils/message'
|
||||||
import { isWorkFlow } from '@/utils/application'
|
import { isWorkFlow } from '@/utils/application'
|
||||||
|
import { baseNodes } from '@/workflow/common/data'
|
||||||
import { t } from '@/locales'
|
import { t } from '@/locales'
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const emit = defineEmits(['refresh'])
|
const emit = defineEmits(['refresh'])
|
||||||
@ -106,6 +128,12 @@ const optimizationPrompt =
|
|||||||
'<data></data>' +
|
'<data></data>' +
|
||||||
t('views.application.applicationForm.dialog.defaultPrompt2')
|
t('views.application.applicationForm.dialog.defaultPrompt2')
|
||||||
|
|
||||||
|
const workflowDefault = ref<any>({
|
||||||
|
edges: [],
|
||||||
|
nodes: baseNodes
|
||||||
|
})
|
||||||
|
const appTemplate = ref('blank')
|
||||||
|
|
||||||
const applicationFormRef = ref()
|
const applicationFormRef = ref()
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
@ -207,6 +235,11 @@ const submitHandle = async (formEl: FormInstance | undefined) => {
|
|||||||
if (!formEl) return
|
if (!formEl) return
|
||||||
await formEl.validate((valid) => {
|
await formEl.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
if (isWorkFlow(applicationForm.value.type) && appTemplate.value === 'blank') {
|
||||||
|
workflowDefault.value.nodes[0].properties.node_data.desc = applicationForm.value.desc
|
||||||
|
workflowDefault.value.nodes[0].properties.node_data.name = applicationForm.value.name
|
||||||
|
applicationForm.value['work_flow'] = workflowDefault.value
|
||||||
|
}
|
||||||
applicationApi.postApplication(applicationForm.value, loading).then((res) => {
|
applicationApi.postApplication(applicationForm.value, loading).then((res) => {
|
||||||
MsgSuccess(t('common.createSuccess'))
|
MsgSuccess(t('common.createSuccess'))
|
||||||
if (isWorkFlow(applicationForm.value.type)) {
|
if (isWorkFlow(applicationForm.value.type)) {
|
||||||
@ -220,6 +253,18 @@ const submitHandle = async (formEl: FormInstance | undefined) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function selectedType(type: string) {
|
||||||
|
appTemplate.value = type
|
||||||
|
}
|
||||||
|
|
||||||
defineExpose({ open })
|
defineExpose({ open })
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scope></style>
|
<style lang="scss" scope>
|
||||||
|
.radio-card {
|
||||||
|
line-height: 22px;
|
||||||
|
&.active {
|
||||||
|
border-color: var(--el-color-primary);
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -4,10 +4,10 @@ import { t } from '@/locales'
|
|||||||
export const startNode = {
|
export const startNode = {
|
||||||
id: WorkflowType.Start,
|
id: WorkflowType.Start,
|
||||||
type: WorkflowType.Start,
|
type: WorkflowType.Start,
|
||||||
x: 180,
|
x: 480,
|
||||||
y: 720,
|
y: 3340,
|
||||||
properties: {
|
properties: {
|
||||||
height: 200,
|
height: 364,
|
||||||
stepName: t('views.applicationWorkflow.nodes.startNode.label'),
|
stepName: t('views.applicationWorkflow.nodes.startNode.label'),
|
||||||
config: {
|
config: {
|
||||||
fields: [
|
fields: [
|
||||||
@ -20,29 +20,45 @@ export const startNode = {
|
|||||||
{
|
{
|
||||||
value: 'time',
|
value: 'time',
|
||||||
label: t('views.applicationWorkflow.nodes.startNode.currentTime')
|
label: t('views.applicationWorkflow.nodes.startNode.currentTime')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'history_context',
|
||||||
|
label: t('views.application.applicationForm.form.historyRecord.label')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'chat_id',
|
||||||
|
label: t('chat.chatId')
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
fields: [{ label: t('views.applicationWorkflow.nodes.startNode.question'), value: 'question' }],
|
||||||
|
globalFields: [
|
||||||
|
{ label: t('views.applicationWorkflow.nodes.startNode.currentTime'), value: 'time' }
|
||||||
|
],
|
||||||
|
showNode: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const baseNode = {
|
export const baseNode = {
|
||||||
id: WorkflowType.Base,
|
id: WorkflowType.Base,
|
||||||
type: WorkflowType.Base,
|
type: WorkflowType.Base,
|
||||||
x: 200,
|
x: 360,
|
||||||
y: 270,
|
y: 2761.3875,
|
||||||
text: '',
|
text: '',
|
||||||
properties: {
|
properties: {
|
||||||
width: 420,
|
height: 728.375,
|
||||||
height: 200,
|
|
||||||
stepName: t('views.applicationWorkflow.nodes.baseNode.label'),
|
stepName: t('views.applicationWorkflow.nodes.baseNode.label'),
|
||||||
input_field_list: [],
|
input_field_list: [],
|
||||||
node_data: {
|
node_data: {
|
||||||
name: '',
|
name: '',
|
||||||
desc: '',
|
desc: '',
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
prologue: t('views.application.applicationForm.form.defaultPrologue')
|
prologue: t('views.application.applicationForm.form.defaultPrologue'),
|
||||||
|
tts_type: 'BROWSER'
|
||||||
},
|
},
|
||||||
config: {}
|
config: {},
|
||||||
|
showNode: true,
|
||||||
|
user_input_config: { title: t('chat.userInput') },
|
||||||
|
user_input_field_list: []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -246,9 +262,7 @@ export const variableAssignNode = {
|
|||||||
height: 252,
|
height: 252,
|
||||||
properties: {
|
properties: {
|
||||||
stepName: t('views.applicationWorkflow.nodes.variableAssignNode.label'),
|
stepName: t('views.applicationWorkflow.nodes.variableAssignNode.label'),
|
||||||
config: {
|
config: {}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,7 +429,7 @@ export const nodeDict: any = {
|
|||||||
[WorkflowType.TextToSpeechNode]: textToSpeechNode,
|
[WorkflowType.TextToSpeechNode]: textToSpeechNode,
|
||||||
[WorkflowType.SpeechToTextNode]: speechToTextNode,
|
[WorkflowType.SpeechToTextNode]: speechToTextNode,
|
||||||
[WorkflowType.ImageGenerateNode]: imageGenerateNode,
|
[WorkflowType.ImageGenerateNode]: imageGenerateNode,
|
||||||
[WorkflowType.VariableAssignNode]: variableAssignNode,
|
[WorkflowType.VariableAssignNode]: variableAssignNode
|
||||||
}
|
}
|
||||||
export function isWorkFlow(type: string | undefined) {
|
export function isWorkFlow(type: string | undefined) {
|
||||||
return type === 'WORK_FLOW'
|
return type === 'WORK_FLOW'
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user