@@ -1,10 +1,7 @@
|
||||
import { nanoid } from "nanoid"
|
||||
import type { Ref } from 'vue'
|
||||
import type { Node, Edge } from '@vue-flow/core'
|
||||
import type { Ref } from "vue"
|
||||
import type { Node, Edge } from "@vue-flow/core"
|
||||
|
||||
/**
|
||||
* 简化的流程操作
|
||||
*/
|
||||
export function useFlowOperations(
|
||||
nodes: Ref<Node[]>,
|
||||
edges: Ref<Edge[]>,
|
||||
@@ -12,24 +9,77 @@ export function useFlowOperations(
|
||||
addEdges: (edges: Edge[]) => void,
|
||||
removeNodes: (nodeIds: string[]) => void,
|
||||
removeEdges: (edgeIds: string[]) => void,
|
||||
saveState: (nodes: Node[], edges: Edge[]) => void
|
||||
saveState: (nodes: Node[], edges: Edge[]) => void,
|
||||
) {
|
||||
// 根据节点类型和handle自动推断标签
|
||||
const getAutoLabel = (
|
||||
sourceNode: any,
|
||||
targetNode: any,
|
||||
sourceHandle: string,
|
||||
targetHandle: string,
|
||||
) => {
|
||||
const sourceType = sourceNode?.data?.originalType || sourceNode?.type
|
||||
const targetType = targetNode?.data?.originalType || targetNode?.type
|
||||
|
||||
// 如果是判断节点
|
||||
if (sourceType === "decision") {
|
||||
// 根据handle ID推断标签
|
||||
if (sourceHandle === "yes") {
|
||||
return "是"
|
||||
} else if (sourceHandle === "no") {
|
||||
return "否"
|
||||
}
|
||||
}
|
||||
|
||||
// 如果是循环节点
|
||||
if (sourceType === "loop") {
|
||||
// 根据handle ID推断标签
|
||||
if (sourceHandle === "continue") {
|
||||
return "继续"
|
||||
} else if (sourceHandle === "exit") {
|
||||
return "退出"
|
||||
}
|
||||
}
|
||||
|
||||
// 如果是循环体回到循环节点
|
||||
if (targetType === "loop") {
|
||||
if (targetHandle === "return") {
|
||||
return "返回"
|
||||
}
|
||||
}
|
||||
// 默认情况
|
||||
return ""
|
||||
}
|
||||
|
||||
// 连接处理
|
||||
const handleConnect = (params: any) => {
|
||||
// 获取源节点和目标节点
|
||||
const sourceNode = nodes.value.find((node) => node.id === params.source)
|
||||
const targetNode = nodes.value.find((node) => node.id === params.target)
|
||||
|
||||
// 自动推断标签
|
||||
const autoLabel = getAutoLabel(
|
||||
sourceNode,
|
||||
targetNode,
|
||||
params.sourceHandle,
|
||||
params.targetHandle,
|
||||
)
|
||||
|
||||
const newEdge: Edge = {
|
||||
id: `edge-${nanoid()}`,
|
||||
source: params.source,
|
||||
target: params.target,
|
||||
sourceHandle: params.sourceHandle,
|
||||
targetHandle: params.targetHandle,
|
||||
type: 'default'
|
||||
type: "default",
|
||||
label: autoLabel,
|
||||
}
|
||||
|
||||
|
||||
addEdges([newEdge])
|
||||
saveState(nodes.value, edges.value)
|
||||
}
|
||||
|
||||
// 边点击删除
|
||||
// 边点击处理 - 单击删除
|
||||
const handleEdgeClick = (event: any) => {
|
||||
removeEdges([event.edge.id])
|
||||
saveState(nodes.value, edges.value)
|
||||
@@ -38,39 +88,39 @@ export function useFlowOperations(
|
||||
// 节点删除
|
||||
const handleNodeDelete = (nodeId: string) => {
|
||||
// 删除相关边
|
||||
const relatedEdges = edges.value.filter(edge =>
|
||||
edge.source === nodeId || edge.target === nodeId
|
||||
const relatedEdges = edges.value.filter(
|
||||
(edge) => edge.source === nodeId || edge.target === nodeId,
|
||||
)
|
||||
if (relatedEdges.length > 0) {
|
||||
removeEdges(relatedEdges.map(edge => edge.id))
|
||||
removeEdges(relatedEdges.map((edge) => edge.id))
|
||||
}
|
||||
|
||||
|
||||
removeNodes([nodeId])
|
||||
saveState(nodes.value, edges.value)
|
||||
}
|
||||
|
||||
// 节点更新
|
||||
const handleNodeUpdate = (nodeId: string, newLabel: string) => {
|
||||
const nodeIndex = nodes.value.findIndex(node => node.id === nodeId)
|
||||
|
||||
const nodeIndex = nodes.value.findIndex((node) => node.id === nodeId)
|
||||
|
||||
if (nodeIndex !== -1) {
|
||||
const oldNode = nodes.value[nodeIndex]
|
||||
|
||||
|
||||
// 创建新的节点对象以确保响应式更新
|
||||
const updatedNode = {
|
||||
...oldNode,
|
||||
data: {
|
||||
...oldNode.data,
|
||||
customLabel: newLabel
|
||||
}
|
||||
customLabel: newLabel,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
// 使用 Vue Flow 的更新方法
|
||||
nodes.value[nodeIndex] = updatedNode
|
||||
|
||||
|
||||
// 强制触发响应式更新
|
||||
nodes.value = [...nodes.value]
|
||||
|
||||
|
||||
saveState(nodes.value, edges.value)
|
||||
}
|
||||
}
|
||||
@@ -84,14 +134,14 @@ export function useFlowOperations(
|
||||
|
||||
// 删除选中的节点和边
|
||||
const deleteSelected = () => {
|
||||
const selectedNodes = nodes.value.filter(node => (node as any).selected)
|
||||
const selectedEdges = edges.value.filter(edge => (edge as any).selected)
|
||||
|
||||
const selectedNodes = nodes.value.filter((node) => (node as any).selected)
|
||||
const selectedEdges = edges.value.filter((edge) => (edge as any).selected)
|
||||
|
||||
if (selectedNodes.length > 0) {
|
||||
removeNodes(selectedNodes.map(node => node.id))
|
||||
removeNodes(selectedNodes.map((node) => node.id))
|
||||
}
|
||||
if (selectedEdges.length > 0) {
|
||||
removeEdges(selectedEdges.map(edge => edge.id))
|
||||
removeEdges(selectedEdges.map((edge) => edge.id))
|
||||
}
|
||||
saveState(nodes.value, edges.value)
|
||||
}
|
||||
@@ -102,6 +152,6 @@ export function useFlowOperations(
|
||||
handleNodeDelete,
|
||||
handleNodeUpdate,
|
||||
clearCanvas,
|
||||
deleteSelected
|
||||
deleteSelected,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,6 +410,75 @@ export function createWebSocketComposable<T extends WebSocketMessage>(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 流程图评分更新消息类型
|
||||
*/
|
||||
export interface FlowchartEvaluationUpdate extends WebSocketMessage {
|
||||
type: "flowchart_evaluation_completed" | "flowchart_evaluation_failed" | "flowchart_evaluation_update"
|
||||
submission_id: string
|
||||
score?: number
|
||||
grade?: string
|
||||
feedback?: string
|
||||
error?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 流程图 WebSocket 连接管理类
|
||||
*/
|
||||
class FlowchartWebSocket extends BaseWebSocket<FlowchartEvaluationUpdate> {
|
||||
constructor() {
|
||||
super({
|
||||
path: "flowchart", // 使用专门的 flowchart WebSocket 路径
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 订阅特定流程图提交的更新
|
||||
*/
|
||||
subscribe(submissionId: string) {
|
||||
const success = this.send({
|
||||
type: "subscribe",
|
||||
submission_id: submissionId,
|
||||
})
|
||||
if (!success) {
|
||||
console.error("[Flowchart WebSocket] 订阅失败: 连接未就绪")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于组件中使用流程图 WebSocket 的 Composable
|
||||
*/
|
||||
export function useFlowchartWebSocket(
|
||||
handler?: MessageHandler<FlowchartEvaluationUpdate>,
|
||||
) {
|
||||
const ws = new FlowchartWebSocket()
|
||||
|
||||
// 如果提供了处理器,添加到实例中
|
||||
if (handler) {
|
||||
ws.addHandler(handler)
|
||||
}
|
||||
|
||||
// 组件卸载时清理资源
|
||||
onUnmounted(() => {
|
||||
if (handler) {
|
||||
ws.removeHandler(handler)
|
||||
}
|
||||
ws.disconnect()
|
||||
})
|
||||
|
||||
return {
|
||||
connect: () => ws.connect(),
|
||||
disconnect: () => ws.disconnect(),
|
||||
subscribe: (submissionId: string) => ws.subscribe(submissionId),
|
||||
scheduleDisconnect: (delay?: number) => ws.scheduleDisconnect(delay),
|
||||
cancelScheduledDisconnect: () => ws.cancelScheduledDisconnect(),
|
||||
status: ws.status,
|
||||
addHandler: (h: MessageHandler<FlowchartEvaluationUpdate>) => ws.addHandler(h),
|
||||
removeHandler: (h: MessageHandler<FlowchartEvaluationUpdate>) => ws.removeHandler(h),
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置更新消息类型
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user