Appearance
节点开发检查清单
开发新节点时按顺序完成以下步骤,任何遗漏都会导致节点在设计器或运行时行为不完整。
必读
节点类型键(如 custom-node)在多个文件中须保持一致,开发前请先确定分类与配置项设计。
开发前准备
- [ ] 确定节点类型键(如
custom-node),该值将在多个文件中保持一致 - [ ] 确定节点所属分类(如
desktop、mouse、flow等) - [ ] 设计节点配置项(需要哪些表单字段)
必须完成的步骤
步骤 1: command-types.ts
文件: src/automa/types/command-types.ts
操作: 在 CommandCategories 数组中找到对应分类,添加命令定义
typescript
{
id: 'custom-node', // 唯一ID
name: '自定义节点', // 显示名称
type: 'custom-node', // 节点类型(必须与 NodeKey 一致)
icon: 'icon-xxx', // 图标
desc: '节点功能描述' // 描述
}验证: 节点应在工作流编辑器的节点面板中显示
步骤 2: node-config.ts - NodeKey 枚举
文件: src/automa/types/node-config.ts
操作: 在 NodeKey 枚举中添加新节点键
typescript
export enum NodeKey {
// ... 其他节点
CUSTOM_NODE = 'custom-node', // 与 command-types.ts 中的 type 一致
}步骤 3: node-config.ts - NodeTypesConfig
文件: src/automa/types/node-config.ts
操作: 在 NodeTypesConfig 数组中添加节点 UI 配置
typescript
{
label: '自定义节点',
key: NodeKey.CUSTOM_NODE,
type: NodeTreeType.NODE,
desc: '节点描述',
color: '#1890ff', // 节点颜色
icon: 'erpfont icon-xxx', // 图标类名
}步骤 4: node-config.ts - 表单配置
文件: src/automa/types/node-config.ts
操作: 定义并导出表单配置
typescript
export const customNodeFormConfig: DynamicFormI = {
showSide: false,
cols: 1,
fields: [
{ label: '字段1', key: 'field1', type: 'text', required: true },
{ label: '字段2', key: 'field2', type: 'integer' },
],
};步骤 5: node-types.ts - 节点接口
文件: src/automa/types/node-types.ts
操作: 定义节点配置接口
typescript
export interface CustomNodeDefinition extends BaseNodeDefinition {
type: NodeKey.CUSTOM_NODE;
config: {
field1: string;
field2?: number;
};
}步骤 6: node-types.ts - 联合类型
文件: src/automa/types/node-types.ts
操作: 在 SpecificNodeDefinition 联合类型中添加
typescript
export type SpecificNodeDefinition =
| DelayNodeDefinition
// ... 其他节点
| CustomNodeDefinition; // 添加这一行步骤 7: node-types.ts - 类型映射
文件: src/automa/types/node-types.ts
操作: 在 NodeDefinitionMap 中添加映射
typescript
export type NodeDefinitionMap = {
// ... 其他映射
'custom-node': CustomNodeDefinition; // 键必须与 NodeKey 值一致
};步骤 8: 创建执行器
文件: src/main/engine/executors/CustomNodeExecutor.ts
操作: 创建执行器类
typescript
import { BaseNodeExecutor } from '../BaseNodeExecutor';
import type { ExecutionContext, NodeExecutionResult } from '@automa/types/engine-types';
import type { CustomNodeDefinition } from '@automa/types/node-types';
import { NodeKey } from '@automa/types/node-config';
export default class CustomNodeExecutor extends BaseNodeExecutor {
type = NodeKey.CUSTOM_NODE;
async execute(node: CustomNodeDefinition, context: ExecutionContext): Promise<NodeExecutionResult> {
const field1 = this.getConfig<string>(node, 'field1', '');
const field2 = this.getConfig<number>(node, 'field2', 0);
try {
// 执行逻辑
return this.success({ field1, field2 });
} catch (error) {
const errMsg = error instanceof Error ? error.message : String(error);
return this.failure(`执行失败: ${errMsg}`);
}
}
}注意:
- 文件名必须以
Executor.ts结尾 - 类必须使用
export default导出 type属性必须与NodeKey枚举值一致
步骤 9: ConfigPanel.vue - 注册表单
文件: src/renderer/pages/workflow/components/ConfigPanel/ConfigPanel.vue
操作 1: 导入表单配置
typescript
import {
// ... 其他导入
customNodeFormConfig,
NodeKey,
} from '@automa/types/node-config';操作 2: 在 currentFormConfig 计算属性的 switch 中添加 case
typescript
case NodeKey.CUSTOM_NODE:
return customNodeFormConfig;步骤 10: 创建流程节点组件
文件: src/renderer/pages/workflow/nodes/CustomNodeNode.vue
操作: 创建 Vue 组件用于在工作流画布中显示节点
vue
<template>
<div class="workflow-node workflow-node--custom" :class="{ 'workflow-node--selected': selected }">
<Handle type="target" :position="targetPosition" />
<div class="workflow-node__header">
<div class="workflow-node__icon" :style="{ color: data.color }">
<i class="erpfont" :class="data.icon" />
</div>
<div class="workflow-node__title">
<span class="workflow-node__label">{{ data.label || '自定义节点' }}</span>
<span class="workflow-node__type">节点分类</span>
</div>
</div>
<div class="workflow-node__body">
<div class="workflow-node__config">
<div v-if="data.field1" class="workflow-node__config-item">
<span class="workflow-node__config-label">字段1</span>
<span class="workflow-node__config-value">{{ data.field1 }}</span>
</div>
</div>
</div>
<Handle type="source" :position="sourcePosition" />
</div>
</template>
<script setup lang="ts">
import { Handle } from '@vue-flow/core';
import { BaseNodeProps } from '../composables/interface';
import { useNodePosition } from '../composables/useNodePosition';
const props = defineProps<BaseNodeProps>();
const { sourcePosition, targetPosition } = useNodePosition(props);
</script>
<style lang="scss" scoped>
@use './node-styles.scss';
.workflow-node--custom {
--node-color: #1890ff;
--node-bg: linear-gradient(135deg, #e6f7ff, #bae7ff);
}
</style>注意:
- 文件名必须以
Node.vue结尾(如CustomNodeNode.vue) - 组件会自动注册,无需手动导入
- 使用
Handle组件定义连接点 - 使用
useNodePosition获取连接点位置 - 在
workflow-node__body中显示节点配置信息 - 使用 CSS 变量
--node-color和--node-bg定义节点样式
开发完成验证
- [ ] 节点在面板中正确显示(图标、名称、描述)
- [ ] 拖拽节点到画布正常
- [ ] 选中节点后配置面板显示表单
- [ ] 表单字段正确渲染
- [ ] 保存配置后数据正确存储
- [ ] 执行流程时节点正常执行
- [ ] 执行结果正确返回
快速排查指南
| 问题现象 | 可能原因 | 检查位置 |
|---|---|---|
| 节点不在面板显示 | 未添加命令定义 | command-types.ts |
| 节点图标/颜色不对 | UI配置错误 | node-config.ts NodeTypesConfig |
| 配置面板为空 | 未注册表单配置 | ConfigPanel.vue |
| 表单字段不显示 | 表单配置错误 | node-config.ts xxxFormConfig |
| 执行时报类型错误 | 接口定义缺失 | node-types.ts |
| 执行器不执行 | 导出方式错误 | executors/ 检查 export default |
| 执行器找不到 | type 不匹配 | 检查 NodeKey 一致性 |