CMVR-BID/src/views/flow/nodes/function/subFlow.vue
zhanghao d733ea8525 feat: 增强流资源管理和节点执行组件
- 增加了检测流资源中引用循环的功能,以防止循环依赖。
- 改进了流引用的验证,以确保节点输出中不存在循环依赖。
- 增强了资源定义清理功能,以便在执行前移除过时的设备ID。
- 已实现复制资源角色的合并,以优化现有资源的优先级并避免重复。
- 更新了LoopIterationResults组件,以管理运行中迭代的自动扩展。
- 增强了NodeState和NodeTitle组件,以支持循环和子流结果的更宽弹出框显示。
- 优化了ParamsDrawer和SubFlowExecutionResults组件,以处理动态参数更新和执行结果。
- 改进了TaskExecutionLog,以统一输出处理并增强用户对日志的可见性。
- 更新了各种参数组件,以简化输入处理并提升用户体验。
- 在代码中添加了全面的注释和文档,以提高可维护性和易理解性。
2026-08-21 15:01:16 +08:00

101 lines
3.6 KiB
Vue
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.

<template>
<div class="node__container" :class="props.model.id">
<NodeState
ref="nodeStateRef"
:state="nodeOperatingStatus"
:runtimes="runtimes"
:popover-width="760"
popper-class="flow-result-popover flow-subflow-result-popover"
>
<template #input>
<JsonViewer :value="inputJsonData" copyable boxed sort theme="light" />
</template>
<template #output>
<SubFlowExecutionResults v-if="nodeOperatingStatus !== 'FAILED'" :data="subFlowExecution" />
<div v-else class="subflow-error">{{ errorInfoData }}</div>
</template>
</NodeState>
<NodeTitle
:icon="props.properties.icon"
:node-id="props.model.id"
:node-properties="props.properties"
:node-type="props.properties.nodeType || 'NONE'"
:node-name="props.properties.name"
:node-desc="props.properties.desc"
@set-node-name="setNodeName"
/>
</div>
</template>
<script setup>
import { computed, onMounted, ref } from 'vue'
import NodeState from '../../components/NodeState.vue'
import NodeTitle from '../../components/NodeTitle.vue'
import SubFlowExecutionResults from '../../components/SubFlowExecutionResults.vue'
import { useFlowEvents } from '../../composables/useFlowEvents'
const props = defineProps({ model: Object, properties: Object })
const emits = defineEmits(['contentChange'])
const { onFlowEvent } = useFlowEvents()
const nodeStateRef = ref(null)
const nodeOperatingStatus = ref('NORMAL')
const runtimes = ref(0)
const inputJsonData = ref({})
const outputJsonData = ref({})
const errorInfoData = ref('')
// 优先使用主页面轮询聚合出的 subFlowExecution;没有内部日志时退回到普通输出,保证旧数据仍可展示。
const subFlowExecution = computed(() => outputJsonData.value?.subFlowExecution || {
name: props.properties?.subFlow?.detectName || props.properties?.name,
versionNo: props.properties?.subFlow?.versionNo,
output: outputJsonData.value,
executions: [],
})
// 子流程输出来自后端运行日志,兼容 JSON 字符串和对象;解析失败时保留原值用于排查。
const parseValue = (value) => {
if (!value) return {}
if (typeof value === 'object') return value
try { return JSON.parse(value) || {} } catch { return value }
}
const setNodeName = (name) => {
const properties = lf.getProperties(props.model.id)
lf.setProperties(props.model.id, { ...properties, name })
emits('contentChange')
}
onMounted(() => {
onFlowEvent('changeNodeState', (data) => {
if (data.nodeId !== props.model.id) return
// 外层子流程节点状态由主页面统一聚合内部日志后派发,这里只负责同步到节点 UI。
nodeOperatingStatus.value = data.status
runtimes.value = data.endTime && data.startTime ? data.endTime - data.startTime : 0
inputJsonData.value = parseValue(data.paramsIn)
outputJsonData.value = parseValue(data.paramsOut)
errorInfoData.value = data?.message || ''
emits('contentChange')
})
onFlowEvent('contentChange', (data) => {
if (data.id !== props.model.id) return
nodeOperatingStatus.value = 'NORMAL'
inputJsonData.value = {}
outputJsonData.value = {}
emits('contentChange')
})
})
defineExpose({ closePopover: () => nodeStateRef.value?.closePopover?.() })
</script>
<style scoped lang="scss">
.node__container { width: 100%; height: auto; }
.subflow-error { color: var(--el-color-danger); line-height: 20px; overflow-wrap: anywhere; }
</style>
<style lang="scss">
.flow-subflow-result-popover {
max-width: min(760px, calc(100vw - 32px));
.result-section__content { max-height: 560px; }
}
</style>