| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- /**
- * 工作流节点共享工具
- *
- * 提取自 WorkflowList.vue 与 WorkflowEditor.vue 中重复的节点配置:
- * - 颜色映射、类型标签、默认数据
- * - parseNodes / thumbnail 渲染辅助
- */
- // ========== 节点类型颜色映射 ==========
- export const nodeTypeColors = {
- userInput: '#10B981',
- llm: '#8B5CF6',
- skill: '#06B6D4',
- agent: '#F59E0B',
- smartAction: '#EC4899',
- condition: '#F97316',
- output: '#EF4444',
- }
- // ========== 节点类型中文标签 ==========
- export const nodeTypeLabels = {
- userInput: '用户输入',
- llm: '大模型处理',
- skill: '技能',
- agent: '智能体',
- smartAction: '智能操作',
- condition: '条件分支',
- output: '输出',
- }
- /**
- * 解析 graphData(字符串或对象)为节点摘要数组
- * @param {string|object} graphData
- * @returns {Array<{type:string, color:string, label:string}>}
- */
- export function parseNodes(graphData) {
- if (!graphData) return []
- try {
- const data = typeof graphData === 'string' ? JSON.parse(graphData) : graphData
- return (data.nodes || []).map(n => ({
- type: n.type,
- color: nodeTypeColors[n.type] || '#64748B',
- label: n.data?.label || n.label || n.type,
- }))
- } catch {
- return []
- }
- }
- /**
- * 解析 graphData 为带位置信息的图形结构(用于缩略图渲染)
- *
- * 返回的 nodes 中 rx/ry 为相对坐标 [0,1]:
- * - 单点或共线时自动居中(避免除零与压扁)
- * - 由调用方(如 NodeThumbnail)映射到具体 SVG 视口
- *
- * @param {string|object} graphData
- * @returns {{
- * hasContent: boolean,
- * nodes: Array<{id:string, type:string, color:string, label:string, rx:number, ry:number}>,
- * edges: Array<{source:object, target:object}>
- * }}
- */
- export function parseGraph(graphData) {
- if (!graphData) return { hasContent: false, nodes: [], edges: [] }
- try {
- const data = typeof graphData === 'string' ? JSON.parse(graphData) : graphData
- const rawNodes = data.nodes || []
- const rawEdges = data.edges || []
- if (!rawNodes.length) return { hasContent: false, nodes: [], edges: [] }
- const xs = rawNodes.map(n => n.position?.x ?? 0)
- const ys = rawNodes.map(n => n.position?.y ?? 0)
- const minX = Math.min(...xs), maxX = Math.max(...xs)
- const minY = Math.min(...ys), maxY = Math.max(...ys)
- const spanX = maxX - minX
- const spanY = maxY - minY
- const nodes = rawNodes.map(n => {
- const nx = n.position?.x ?? 0
- const ny = n.position?.y ?? 0
- return {
- id: String(n.id ?? ''),
- type: n.type,
- color: nodeTypeColors[n.type] || '#64748B',
- label: n.data?.label || n.label || n.type,
- rx: spanX > 0 ? (nx - minX) / spanX : 0.5,
- ry: spanY > 0 ? (ny - minY) / spanY : 0.5,
- }
- })
- const nodeMap = new Map(nodes.map(n => [n.id, n]))
- const edges = (rawEdges || [])
- .map(e => ({
- source: nodeMap.get(String(e.source)),
- target: nodeMap.get(String(e.target)),
- }))
- .filter(e => e.source && e.target)
- return { hasContent: true, nodes, edges }
- } catch {
- return { hasContent: false, nodes: [], edges: [] }
- }
- }
- /**
- * 根据节点类型返回默认 data 字段(与 WorkflowEditor.getDefaultData 保持一致)
- */
- export function getDefaultData(type) {
- switch (type) {
- case 'userInput':
- return { label: '用户输入', variables: [] }
- case 'llm':
- return {
- label: '大模型处理',
- modelId: null,
- systemPrompt: '',
- userPrompt: '',
- inputs: [],
- outputs: [{ name: 'result', label: 'LLM 输出', type: 'string', description: '', required: false }],
- failStrategy: 'abort',
- }
- case 'agent':
- return { label: '智能体', agentId: '', agentName: '', modelId: null, failStrategy: 'abort' }
- case 'skill':
- return { label: '技能', skillId: '', skillName: '', modelId: null, failStrategy: 'abort' }
- case 'smartAction':
- return {
- label: '智能操作',
- actionPrompt: '',
- modelId: null,
- inputs: [],
- outputs: [{ name: 'result', label: '操作结果', type: 'string', description: '', required: false }],
- failStrategy: 'abort',
- }
- case 'condition':
- return { label: '条件分支', conditions: [{ type: 'IF', expression: '' }] }
- case 'output':
- return { label: '输出', fields: [{ name: 'result', label: '输出结果', type: 'string', description: '', required: false }] }
- default:
- return { label: '节点' }
- }
- }
|