Files
urbanLifeline/江西城市生命线-可交互原型/frontend/src/stores/workflow.js
2025-12-12 18:32:14 +08:00

141 lines
3.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
})