CMVR-IOT-UI/src/views/flow/components/ParamsDrawer.vue
lixiaolong b3dae8db39 feat(flow): 添加子流程功能并优化参数引用逻辑
- 新增子流程节点类型,支持在同一项目中执行已发布工作流
- 添加子流程节点UI组件和相关配置选项
- 重构参数引用逻辑,使用getUpstreamInput替代getInput方法
- 优化cascader组件属性设置,统一使用props配置checkStrictly
- 修正多个参数组件中的handleTypeChange和cascaderChange函数参数传递
- 添加流程输出参数管理功能,支持引用来源选择和类型识别
- 实现子流程运行时状态管理和迭代输出处理
- 增加循环引用检测和资源验证功能
- 更新API接口,添加子流程选项获取方法
- 修复流程引用和依赖关系处理逻辑
2026-08-21 11:48:10 +08:00

162 lines
4.9 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>
<el-drawer
:model-value="props.drawer"
custom-class="flow-params-drawer"
:title="props.data.properties?.name || '参数配置'"
class="flow-params-drawer"
:size="drawerSize"
append-to-body
destroy-on-close
:close-on-click-modal="false"
:before-close="confirmSave"
>
<component
:is="currentComponent"
ref="paramsComponentRef"
:data="props.data"
v-bind="componentExtraProps"
@save-success="handleSaveSuccess"
@save-error="handleSaveError"
@extract-step="handleExtractStep"
/>
</el-drawer>
</template>
<script setup>
import { ref, computed } from 'vue'
import { emitter } from '@/utils/eventBus'
// 导入各子组件
import StartParams from './params/StartParams.vue'
import BasicNodeParams from './params/BasicNodeParams.vue'
import CodeNodeParams from './params/CodeNodeParams.vue'
import HttpNodeParams from './params/HttpNodeParams.vue'
import SdAgentNodeParams from './params/SdAgentNodeParams.vue'
import RecognizeNodeParams from './params/RecognizeNodeParams.vue'
import DeviceUniversal from './params/DeviceUniversal.vue'
import SwitchNodeParams from './params/SwitchNodeParams.vue'
import ActionQueueParams from './params/ActionQueueParams.vue'
import MediaAnalysisParams from './params/MediaAnalysisParams.vue'
import ImageAnalysisParams from './params/ImageAnalysisParams.vue'
import EndParams from './params/EndParams.vue'
import SubFlowParams from './params/SubFlowParams.vue'
const props = defineProps({
drawer: Boolean,
data: Object,
flowId: String
})
const emits = defineEmits(['close', 'extract-step'])
const paramsComponentRef = ref(null)
/**
* 分支条件包含左值、运算符和右值三列,仅为分支节点提供更宽的编辑空间。
*/
const drawerSize = computed(() => (
props.data?.type === 'branch' ? 'min(920px, 96vw)' : 'min(560px, 92vw)'
))
// 根据节点类型决定渲染哪个子组件
const currentComponent = computed(() => {
const type = props.data?.type
if (type === 'start') return StartParams
if (type === 'end') return EndParams
if (type === 'subFlow') return SubFlowParams
if (['currentLoop', 'serviceNode', 'sleep', 'loop'].includes(type)) return BasicNodeParams
if (type === 'code') return CodeNodeParams
if (type === 'http') return HttpNodeParams
if (type === 'sdAgent') return SdAgentNodeParams
if (type === 'recognize') return RecognizeNodeParams
if (['deviceUniversal', 'device_universal'].includes(type)) return DeviceUniversal
if (type === 'actionQueue') return ActionQueueParams
if (type === 'mediaAnalysis') return MediaAnalysisParams
// 图片分析支持多图、参考图和自由提示词输出,使用独立面板保持媒体分析面板聚焦音视频。
if (type === 'imageAnalysis') return ImageAnalysisParams
if (type === 'branch') return SwitchNodeParams
return null
})
const componentExtraProps = computed(() => (
props.data?.type === 'subFlow' ? { flowId: props.flowId } : {}
))
// 这里提供一个公开方法供父组件调用
/**
* 确认 confirmSave 对应的数据或交互;作用范围仅限当前组件或模块。
*/
const confirmSave = async () => {
if (paramsComponentRef.value && typeof paramsComponentRef.value.validateAndSave === 'function') {
await paramsComponentRef.value.validateAndSave()
} else {
emits('close')
}
}
// 暴露给父组件使用
defineExpose({ confirmSave })
// 保存成功 / 失败处理
/**
* 处理 handleSaveSuccess 对应的数据或交互;作用范围仅限当前组件或模块。
*/
const handleSaveSuccess = () => {
emitter.emit('setProperties', { id: props.data.id })
emitter.emit("throwAnError", { id: props.data.id, hasError: false, type: props.data.type });
// 无错误,关闭抽屉
emits('close')
}
/**
* 处理 handleSaveError 对应的数据或交互;作用范围仅限当前组件或模块。
*/
const handleSaveError = () => {
emitter.emit('setProperties', { id: props.data.id })
emitter.emit("throwAnError", { id: props.data.id, hasError: true, type: props.data.type });
emits('close')
}
const handleExtractStep = (payload) => emits('extract-step', payload)
// 组件卸载时清理事件监听
// 注意:emitter.off 应在各子组件中自行清理,父组件不再重复
</script>
<style lang="scss">
.flow-params-drawer {
.el-drawer__header {
min-height: 62px;
margin-bottom: 0 !important;
padding: 0 20px;
border-bottom: 1px solid #e4e8ef;
color: #1f2937;
font-size: 16px;
font-weight: 650;
}
.el-drawer__body {
padding: 0 20px 24px;
overflow-x: hidden;
}
.el-collapse {
border-top: 0;
}
.el-collapse-item__header {
height: 50px;
color: #344054;
font-size: 13px;
font-weight: 650;
}
.form__container {
padding: 4px 0 10px;
}
}
</style>