feat(web): add Vue Flow editor and flow trace viewer
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="inbound-flow">
|
||||
<el-form :model="form" label-width="100px">
|
||||
<el-form-item label="流程编码">
|
||||
<el-input v-model="form.flowCode" placeholder="flow_code" />
|
||||
@@ -7,63 +7,105 @@
|
||||
<el-form-item label="流程名称">
|
||||
<el-input v-model="form.flowName" placeholder="流程名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="节点配置">
|
||||
<el-input v-model="nodesJson" type="textarea" :rows="8" placeholder='[{"nodeType":"receive"},{"nodeType":"intent","intent":"rescue_request"},{"nodeType":"webhook","webhookUrl":"http://..."}]' />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleCreate">保存流程</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-divider />
|
||||
|
||||
<el-table :data="flows" border>
|
||||
<el-table-column prop="id" label="ID" width="80" />
|
||||
<el-table-column prop="flowCode" label="流程编码" />
|
||||
<el-table-column prop="flowName" label="名称" />
|
||||
<el-table-column prop="status" label="状态" />
|
||||
</el-table>
|
||||
<div class="flow-canvas">
|
||||
<VueFlow v-model="elements" fit-view-on-init>
|
||||
<Background pattern-color="#aaa" :gap="16" />
|
||||
<Controls />
|
||||
</VueFlow>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, computed, onMounted } from 'vue'
|
||||
import { reactive, ref } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { createFlowDefinition, listFlowDefinitions } from '@/api/flow'
|
||||
import { VueFlow } from '@vue-flow/core'
|
||||
import { Background } from '@vue-flow/background'
|
||||
import { Controls } from '@vue-flow/controls'
|
||||
import { createFlowDefinition } from '@/api/flow'
|
||||
import '@vue-flow/core/dist/style.css'
|
||||
import '@vue-flow/core/dist/theme-default.css'
|
||||
|
||||
const form = reactive({
|
||||
flowCode: '',
|
||||
flowName: '',
|
||||
nodes: [] as any[],
|
||||
})
|
||||
|
||||
const nodesJson = computed({
|
||||
get: () => JSON.stringify(form.nodes, null, 2),
|
||||
set: (val) => {
|
||||
try { form.nodes = JSON.parse(val) } catch {}
|
||||
const elements = ref<any[]>([
|
||||
{
|
||||
id: '1',
|
||||
type: 'input',
|
||||
label: '接收消息',
|
||||
position: { x: 250, y: 5 },
|
||||
data: { nodeType: 'receive' },
|
||||
},
|
||||
})
|
||||
|
||||
const flows = ref<any[]>([])
|
||||
|
||||
async function loadFlows() {
|
||||
try {
|
||||
const res: any = await listFlowDefinitions()
|
||||
flows.value = res.data || []
|
||||
} catch (e: any) {
|
||||
ElMessage.error(e.message)
|
||||
}
|
||||
}
|
||||
{
|
||||
id: '2',
|
||||
label: '意图识别',
|
||||
position: { x: 250, y: 120 },
|
||||
data: { nodeType: 'intent', intent: 'rescue_request' },
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
label: 'Webhook 推送',
|
||||
position: { x: 250, y: 240 },
|
||||
data: { nodeType: 'webhook', webhookUrl: '' },
|
||||
},
|
||||
{ id: 'e1-2', source: '1', target: '2' },
|
||||
{ id: 'e2-3', source: '2', target: '3' },
|
||||
])
|
||||
|
||||
async function handleCreate() {
|
||||
try {
|
||||
const res: any = await createFlowDefinition(form)
|
||||
flows.value.unshift(res.data)
|
||||
const nodes = elements.value
|
||||
.filter((el) => !('source' in el))
|
||||
.map((el) => {
|
||||
const { nodeType, ...config } = el.data || {}
|
||||
return {
|
||||
nodeType,
|
||||
config,
|
||||
position: el.position,
|
||||
}
|
||||
})
|
||||
|
||||
const edges = elements.value
|
||||
.filter((el) => 'source' in el)
|
||||
.map((el) => ({
|
||||
source: el.source,
|
||||
target: el.target,
|
||||
}))
|
||||
|
||||
const res: any = await createFlowDefinition({
|
||||
flowCode: form.flowCode,
|
||||
flowName: form.flowName,
|
||||
flowType: 'inbound',
|
||||
definitionJson: { nodes, edges },
|
||||
})
|
||||
|
||||
ElMessage.success('保存成功')
|
||||
console.log(res)
|
||||
} catch (e: any) {
|
||||
ElMessage.error(e.message)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(loadFlows)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.inbound-flow {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - 120px);
|
||||
}
|
||||
|
||||
.flow-canvas {
|
||||
flex: 1;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
min-height: 400px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user