Files
urbanLifeline/江西城市生命线-可交互原型/frontend/src/stores/workflow.js

141 lines
3.9 KiB
JavaScript
Raw Normal View History

2025-12-12 18:32:14 +08:00
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
}
})