141 lines
3.9 KiB
JavaScript
141 lines
3.9 KiB
JavaScript
import { defineStore } from 'pinia'
|
||
import { ref, computed } from 'vue'
|
||
|
||
export const useWorkflowStore = defineStore('workflow', () => {
|
||
// 节点列表
|
||
const nodes = ref([])
|
||
|
||
// 连接线列表
|
||
const connections = ref([])
|
||
|
||
// 选中的节点ID
|
||
const selectedNodeId = ref(null)
|
||
|
||
// 节点ID计数器
|
||
let nodeIdCounter = 1
|
||
|
||
// 节点类型定义
|
||
const nodeTypes = [
|
||
{ type: 'start', label: '开始', icon: '▶', color: '#10b981', category: 'control' },
|
||
{ type: 'end', label: '结束', icon: '⏹', color: '#ef4444', category: 'control' },
|
||
{ type: 'llm', label: 'LLM 模型', icon: '🤖', color: '#7c3aed', category: 'ai' },
|
||
{ type: 'knowledge', label: '知识库', icon: '📚', color: '#3b82f6', category: 'ai' },
|
||
{ type: 'condition', label: '条件判断', icon: '⋔', color: '#f59e0b', category: 'logic' },
|
||
{ type: 'code', label: '代码执行', icon: '{ }', color: '#6366f1', category: 'logic' },
|
||
{ type: 'http', label: 'HTTP 请求', icon: '🌐', color: '#14b8a6', category: 'integration' },
|
||
{ type: 'variable', label: '变量赋值', icon: '𝑥=', color: '#8b5cf6', category: 'logic' },
|
||
{ type: 'template', label: '模板转换', icon: '📝', color: '#ec4899', category: 'transform' },
|
||
{ type: 'loop', label: '循环', icon: '↻', color: '#f97316', category: 'logic' }
|
||
]
|
||
|
||
// 添加节点
|
||
const addNode = (type, position) => {
|
||
const nodeType = nodeTypes.find(n => n.type === type)
|
||
if (!nodeType) return null
|
||
|
||
const newNode = {
|
||
id: `node_${nodeIdCounter++}`,
|
||
type: type,
|
||
label: nodeType.label,
|
||
icon: nodeType.icon,
|
||
color: nodeType.color,
|
||
x: position.x,
|
||
y: position.y,
|
||
width: 180,
|
||
height: 60,
|
||
inputs: type !== 'start' ? [{ id: 'in_1', label: '输入' }] : [],
|
||
outputs: type !== 'end' ? [{ id: 'out_1', label: '输出' }] : []
|
||
}
|
||
|
||
nodes.value.push(newNode)
|
||
return newNode
|
||
}
|
||
|
||
// 更新节点位置
|
||
const updateNodePosition = (nodeId, x, y) => {
|
||
const node = nodes.value.find(n => n.id === nodeId)
|
||
if (node) {
|
||
node.x = x
|
||
node.y = y
|
||
}
|
||
}
|
||
|
||
// 删除节点
|
||
const deleteNode = (nodeId) => {
|
||
const index = nodes.value.findIndex(n => n.id === nodeId)
|
||
if (index > -1) {
|
||
nodes.value.splice(index, 1)
|
||
// 删除相关连接
|
||
connections.value = connections.value.filter(
|
||
c => c.sourceNodeId !== nodeId && c.targetNodeId !== nodeId
|
||
)
|
||
}
|
||
if (selectedNodeId.value === nodeId) {
|
||
selectedNodeId.value = null
|
||
}
|
||
}
|
||
|
||
// 添加连接
|
||
const addConnection = (sourceNodeId, sourcePortId, targetNodeId, targetPortId) => {
|
||
// 检查是否已存在相同连接
|
||
const exists = connections.value.some(
|
||
c => c.sourceNodeId === sourceNodeId &&
|
||
c.sourcePortId === sourcePortId &&
|
||
c.targetNodeId === targetNodeId &&
|
||
c.targetPortId === targetPortId
|
||
)
|
||
if (exists) return null
|
||
|
||
const newConnection = {
|
||
id: `conn_${Date.now()}`,
|
||
sourceNodeId,
|
||
sourcePortId,
|
||
targetNodeId,
|
||
targetPortId
|
||
}
|
||
connections.value.push(newConnection)
|
||
return newConnection
|
||
}
|
||
|
||
// 删除连接
|
||
const deleteConnection = (connectionId) => {
|
||
const index = connections.value.findIndex(c => c.id === connectionId)
|
||
if (index > -1) {
|
||
connections.value.splice(index, 1)
|
||
}
|
||
}
|
||
|
||
// 选中节点
|
||
const selectNode = (nodeId) => {
|
||
selectedNodeId.value = nodeId
|
||
}
|
||
|
||
// 清空画布
|
||
const clearCanvas = () => {
|
||
nodes.value = []
|
||
connections.value = []
|
||
selectedNodeId.value = null
|
||
nodeIdCounter = 1
|
||
}
|
||
|
||
// 获取节点
|
||
const getNode = (nodeId) => {
|
||
return nodes.value.find(n => n.id === nodeId)
|
||
}
|
||
|
||
return {
|
||
nodes,
|
||
connections,
|
||
selectedNodeId,
|
||
nodeTypes,
|
||
addNode,
|
||
updateNodePosition,
|
||
deleteNode,
|
||
addConnection,
|
||
deleteConnection,
|
||
selectNode,
|
||
clearCanvas,
|
||
getNode
|
||
}
|
||
})
|