feat: 新增执行记录实体与文件上传能力
This commit is contained in:
@@ -1,119 +1,449 @@
|
||||
package node
|
||||
|
||||
// ======================== 【常量定义:所有中文文案放这里!】 ========================
|
||||
// 分组名称
|
||||
const (
|
||||
NodeGroupNameComponent = "组件"
|
||||
NodeGroupNameBase = "基础"
|
||||
NodeGroupNameCustom = "自定义"
|
||||
)
|
||||
|
||||
// 节点名称
|
||||
const (
|
||||
NodeNameTextModel = "生成文案"
|
||||
NodeNameImageModel = "生成图片"
|
||||
NodeNameVideoModel = "生成视频"
|
||||
NodeNameAudioModel = "生成音频"
|
||||
NodeNameBatchModel = "批量处理一起返回"
|
||||
NodeNameDataConversionModel = "参数转换"
|
||||
NodeNameModel = "模型"
|
||||
NodeNameMerge = "结果合并"
|
||||
NodeNameDataMerge = "结果汇集"
|
||||
NodeNameJudge = "条件判断"
|
||||
NodeNameLoop = "循环"
|
||||
NodeNameForm = "表单"
|
||||
NodeSubFlow = "子流程"
|
||||
NodeNameHttp = "HTTP(S)接口"
|
||||
NodeNameCustomNode = "自定义节点"
|
||||
NodeNameSystemSum = "系统-结果汇总"
|
||||
)
|
||||
|
||||
// 表单字段 Label
|
||||
const (
|
||||
FormLabelApiKey = "API Key"
|
||||
FormLabelModel = "模型名称"
|
||||
FormLabelCondition = "判断条件"
|
||||
)
|
||||
|
||||
// ======================== 枚举类型 ========================
|
||||
// NodeGroup 节点分组标识
|
||||
type NodeGroup string
|
||||
|
||||
const (
|
||||
NodeGroupComponent NodeGroup = "component"
|
||||
NodeGroupBase NodeGroup = "base"
|
||||
NodeGroupCustom NodeGroup = "custom"
|
||||
)
|
||||
|
||||
// NodeType 节点类型标识
|
||||
type NodeType string
|
||||
|
||||
// 分组常量定义
|
||||
const (
|
||||
// 组件
|
||||
NodeTypeTextModel NodeType = "text_model"
|
||||
NodeTypeImageModel NodeType = "image_model"
|
||||
NodeTypeVideoModel NodeType = "video_model"
|
||||
NodeTypeAudioModel NodeType = "audio_model"
|
||||
NodeTypeBatchModel NodeType = "batch_model"
|
||||
NodeTypeDataConversionModel NodeType = "data_conversion_model"
|
||||
// 基础
|
||||
NodeTypeModel NodeType = "model"
|
||||
NodeTypeMerge NodeType = "merge"
|
||||
NodeTypeDataMerge NodeType = "data_merge"
|
||||
NodeTypeJudge NodeType = "judge"
|
||||
NodeTypeForm NodeType = "form"
|
||||
NodeTypeIntent NodeType = "intent"
|
||||
NodeTypeSubFlow NodeType = "sub_flow"
|
||||
NodeTypeHttp NodeType = "http"
|
||||
// 自定义
|
||||
NodeTypeCustomNode NodeType = "custom_node"
|
||||
// 系统
|
||||
NodeTypeSystemSum NodeType = "system_sum"
|
||||
NodeGroupBase NodeGroup = "base"
|
||||
NodeGroupSystem NodeGroup = "system"
|
||||
)
|
||||
|
||||
// 节点类型常量定义
|
||||
const (
|
||||
ModelTypeText = 100
|
||||
ModelTypeImage = 200
|
||||
ModelTypeAudio = 300
|
||||
ModelTypeModality = 500
|
||||
ModelTypeVideo = 600
|
||||
NodeTypeStart NodeType = "__start__"
|
||||
NodeTypeModel NodeType = "model"
|
||||
NodeTypeDataMerge NodeType = "data_merge"
|
||||
NodeTypeForm NodeType = "form"
|
||||
NodeTypeSubFlow NodeType = "sub_flow"
|
||||
NodeTypeHttp NodeType = "http"
|
||||
NodeTypeSystemSum NodeType = "system_sum"
|
||||
NodeTypeScriptTranscribe NodeType = "script_transcribe"
|
||||
)
|
||||
|
||||
// ======================== 结构定义 ========================
|
||||
type NodeFormField struct {
|
||||
Value any `json:"value"`
|
||||
Field string `json:"field"`
|
||||
Label string `json:"label"` // 从常量来
|
||||
Type string `json:"type"`
|
||||
Required bool `json:"required"`
|
||||
Default any `json:"default,omitempty"`
|
||||
Options []SelectOption `json:"options"`
|
||||
Expand any `json:"expand"`
|
||||
FieldConstraint any `json:"fieldConstraint"`
|
||||
// NodeGroupMeta 节点分组元数据
|
||||
type NodeGroupMeta struct {
|
||||
Key NodeGroup `json:"key"` // 后端存储标识
|
||||
Name string `json:"name"` // 前端展示中文名称
|
||||
}
|
||||
|
||||
// NodeTypeMeta 节点元数据
|
||||
type NodeTypeMeta struct {
|
||||
Key NodeType `json:"key"` // 节点类型标识
|
||||
Name string `json:"name"` // 节点中文名称
|
||||
Group NodeGroup `json:"group"` // 所属分组
|
||||
Sort int `json:"sort"` // UI排序字段
|
||||
Desc string `json:"desc,omitempty"` // 可选:节点简介
|
||||
BatchExecOption bool `json:"batchExecOption"`
|
||||
PreToolOption bool `json:"preToolOption"`
|
||||
PostToolOption bool `json:"postToolOption"`
|
||||
IsSaveFileOption bool `json:"isSaveFileOption"`
|
||||
FormConfigOption bool `json:"formConfigOption"`
|
||||
ModelConfigOption bool `json:"modelConfigOption"`
|
||||
SkillOption bool `json:"skillOption"`
|
||||
PromptOption bool `json:"promptOption"`
|
||||
NegativePromptOption bool `json:"negativePromptOption"`
|
||||
PresetOption []NodePresetField `json:"presetOption"`
|
||||
OutputField []string `json:"outputField"`
|
||||
}
|
||||
|
||||
type NodePresetField struct {
|
||||
Value string `json:"value"`
|
||||
Field string `json:"field"`
|
||||
Label string `json:"label"`
|
||||
Type string `json:"type"`
|
||||
IsFormField bool `json:"isFormField"`
|
||||
Constraint FieldConstraint `json:"constraint"`
|
||||
Required bool `json:"required"`
|
||||
Options []SelectOption `json:"options"`
|
||||
}
|
||||
|
||||
// FieldConstraint 字段约束
|
||||
type FieldConstraint struct {
|
||||
// 数字类型:int、float、double、string
|
||||
Type string `json:"type" dc:"类型"`
|
||||
Min any `json:"min" dc:"最小值"`
|
||||
Max any `json:"max" dc:"最大值"`
|
||||
}
|
||||
|
||||
type SelectOption struct {
|
||||
Label string `json:"label"`
|
||||
Value string `json:"value"`
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
Config []NodePresetField `json:"config"`
|
||||
}
|
||||
|
||||
type ModelItem struct {
|
||||
ModelName string `json:"modelName"`
|
||||
ModelForm []NodeFormField `json:"modelForm"`
|
||||
// NodeGroupTree 对外输出树形结构:分组 + 分组下所有节点
|
||||
type NodeGroupTree struct {
|
||||
Group NodeGroupMeta `json:"group"`
|
||||
Nodes []NodeTypeMeta `json:"nodes"`
|
||||
}
|
||||
|
||||
type NodeItem struct {
|
||||
NodeId string `json:"nodeId"`
|
||||
NodeCode NodeType `json:"nodeCode"`
|
||||
ModelType int `json:"modelType"`
|
||||
NodeName string `json:"nodeName"` // 从常量来
|
||||
SkillOption bool `json:"skillOption"`
|
||||
PromptOption bool `json:"promptOption"`
|
||||
IsSaveFile bool `json:"isSaveFile"`
|
||||
FormConfig []NodeFormField `json:"formConfig"`
|
||||
ModelConfig []ModelItem `json:"modelConfig"`
|
||||
// ===================== 元数据集中注册区(英文标识+中文文案统一维护) =====================
|
||||
var NodeGroupMetaList = []NodeGroupMeta{
|
||||
{
|
||||
Key: NodeGroupBase,
|
||||
Name: "基础",
|
||||
},
|
||||
}
|
||||
|
||||
type NodeGroupItem struct {
|
||||
Group NodeGroup `json:"group"`
|
||||
Label string `json:"label"` // 从常量来
|
||||
Items []NodeItem `json:"items"`
|
||||
var NodeTypeMetaList = []NodeTypeMeta{
|
||||
{
|
||||
Key: NodeTypeModel,
|
||||
Name: "模型",
|
||||
Group: NodeGroupBase,
|
||||
Sort: 1,
|
||||
Desc: "模型调用节点,可配置模型参数、模型配置、技能、提示语、结果汇集、结果保存、结果返回、结果展示等信息。",
|
||||
BatchExecOption: true,
|
||||
PreToolOption: true,
|
||||
PostToolOption: true,
|
||||
IsSaveFileOption: true,
|
||||
FormConfigOption: false,
|
||||
ModelConfigOption: true,
|
||||
SkillOption: false,
|
||||
PromptOption: true,
|
||||
NegativePromptOption: true,
|
||||
},
|
||||
{
|
||||
Key: NodeTypeDataMerge,
|
||||
Name: "结果汇集",
|
||||
Group: NodeGroupBase,
|
||||
Sort: 2,
|
||||
Desc: "结果汇集节点,可配置结果汇集方式、结果保存、结果返回、结果展示等信息。",
|
||||
BatchExecOption: false,
|
||||
PreToolOption: false,
|
||||
PostToolOption: false,
|
||||
IsSaveFileOption: false,
|
||||
FormConfigOption: false,
|
||||
ModelConfigOption: false,
|
||||
SkillOption: false,
|
||||
PromptOption: false,
|
||||
NegativePromptOption: false,
|
||||
},
|
||||
{
|
||||
Key: NodeTypeForm,
|
||||
Name: "表单",
|
||||
Group: NodeGroupBase,
|
||||
Sort: 3,
|
||||
Desc: "表单节点,可配置表单字段、表单配置、结果汇集、结果保存、结果返回、结果展示等信息。",
|
||||
BatchExecOption: false,
|
||||
PreToolOption: false,
|
||||
PostToolOption: false,
|
||||
IsSaveFileOption: false,
|
||||
FormConfigOption: true,
|
||||
ModelConfigOption: false,
|
||||
SkillOption: false,
|
||||
PromptOption: false,
|
||||
NegativePromptOption: false,
|
||||
},
|
||||
{
|
||||
Key: NodeTypeSubFlow,
|
||||
Name: "子流程",
|
||||
Group: NodeGroupBase,
|
||||
Sort: 4,
|
||||
PresetOption: []NodePresetField{
|
||||
{
|
||||
Field: "maxConcurrency",
|
||||
Label: "生成次数",
|
||||
Type: "input",
|
||||
Value: "1",
|
||||
IsFormField: true,
|
||||
Constraint: FieldConstraint{
|
||||
Type: "int",
|
||||
Min: 1,
|
||||
Max: 10,
|
||||
},
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Key: NodeTypeHttp,
|
||||
Name: "HTTP(S)接口",
|
||||
Group: NodeGroupBase,
|
||||
Sort: 5,
|
||||
Desc: "HTTP(S)接口节点,可配置HTTP(S)接口地址、请求方式、请求头、请求体、结果返回结构、结果返回方式、结果返回结构、结果返回方式等信息。",
|
||||
BatchExecOption: false,
|
||||
PreToolOption: true,
|
||||
PostToolOption: true,
|
||||
IsSaveFileOption: false,
|
||||
FormConfigOption: false,
|
||||
ModelConfigOption: false,
|
||||
SkillOption: false,
|
||||
PromptOption: false,
|
||||
NegativePromptOption: false,
|
||||
PresetOption: []NodePresetField{
|
||||
{
|
||||
Field: "method",
|
||||
Label: "请求方式",
|
||||
Type: "select",
|
||||
Required: true,
|
||||
Options: []SelectOption{
|
||||
{Key: "GET", Value: "GET"},
|
||||
{Key: "POST", Value: "POST"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Field: "url",
|
||||
Label: "请求地址",
|
||||
Type: "input",
|
||||
Constraint: FieldConstraint{
|
||||
Type: "string",
|
||||
Min: 1,
|
||||
Max: -1,
|
||||
},
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Field: "headers",
|
||||
Label: "请求头(支持Authorization鉴权)",
|
||||
Type: "keyValue",
|
||||
Required: false,
|
||||
},
|
||||
{
|
||||
Field: "bodyType",
|
||||
Label: "请求体类型",
|
||||
Type: "select",
|
||||
Required: true,
|
||||
Options: []SelectOption{
|
||||
{Key: "None", Value: "无"},
|
||||
{Key: "JSON", Value: "JSON"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Field: "body",
|
||||
Label: "请求体内容",
|
||||
Type: "schemaJson",
|
||||
Required: false,
|
||||
},
|
||||
{
|
||||
Field: "response",
|
||||
Label: "结果返回结构",
|
||||
Type: "schemaJson",
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Field: "responseType",
|
||||
Label: "结果返回方式",
|
||||
Type: "select",
|
||||
Required: true,
|
||||
Options: []SelectOption{
|
||||
{Key: "sync", Value: "同步返回"},
|
||||
{Key: "callback", Value: "等候回调", Config: []NodePresetField{
|
||||
{
|
||||
Field: "callbackUrl",
|
||||
Label: "回调地址(只需要填写字段名称)",
|
||||
Type: "input",
|
||||
Constraint: FieldConstraint{
|
||||
Type: "string",
|
||||
Min: 1,
|
||||
Max: -1,
|
||||
},
|
||||
Required: true,
|
||||
},
|
||||
}},
|
||||
{Key: "pull", Value: "主动拉取", Config: []NodePresetField{
|
||||
{
|
||||
Field: "method",
|
||||
Label: "请求方式",
|
||||
Type: "select",
|
||||
Required: true,
|
||||
Options: []SelectOption{
|
||||
{Key: "GET", Value: "GET"},
|
||||
{Key: "POST", Value: "POST"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Field: "url",
|
||||
Label: "请求地址",
|
||||
Type: "input",
|
||||
Constraint: FieldConstraint{
|
||||
Type: "string",
|
||||
Min: 1,
|
||||
Max: -1,
|
||||
},
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Field: "headers",
|
||||
Label: "请求头(支持Authorization鉴权)",
|
||||
Type: "keyValue",
|
||||
Required: false,
|
||||
},
|
||||
{
|
||||
Field: "bodyType",
|
||||
Label: "请求体类型",
|
||||
Type: "select",
|
||||
Required: true,
|
||||
Options: []SelectOption{
|
||||
{Key: "None", Value: "无"},
|
||||
{Key: "JSON", Value: "JSON"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Field: "body",
|
||||
Label: "请求体内容",
|
||||
Type: "schemaJson",
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Field: "response",
|
||||
Label: "结果返回结构",
|
||||
Type: "schemaJson",
|
||||
Required: true,
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Key: NodeTypeScriptTranscribe,
|
||||
Name: "脚本转写",
|
||||
Group: NodeGroupBase,
|
||||
Sort: 6,
|
||||
Desc: "脚本转写节点,把文案/视频分析结果通过大模型转写为结构化分镜脚本([]Shot),作为视频生成节点的 shots 输入。",
|
||||
BatchExecOption: false,
|
||||
PreToolOption: false,
|
||||
PostToolOption: false,
|
||||
IsSaveFileOption: false,
|
||||
FormConfigOption: false,
|
||||
ModelConfigOption: true,
|
||||
SkillOption: false,
|
||||
PromptOption: false,
|
||||
NegativePromptOption: false,
|
||||
PresetOption: []NodePresetField{
|
||||
{
|
||||
Field: "totalDuration",
|
||||
Label: "视频总时长",
|
||||
Type: "input",
|
||||
Constraint: FieldConstraint{
|
||||
Type: "int",
|
||||
Min: 1,
|
||||
Max: 300,
|
||||
},
|
||||
Required: true,
|
||||
},
|
||||
{
|
||||
Field: "modelId",
|
||||
Label: "视频模型",
|
||||
Type: "select",
|
||||
Required: true,
|
||||
Options: []SelectOption{},
|
||||
},
|
||||
},
|
||||
OutputField: []string{"prompt", "duration", "seed", "negative_prompt", "reference_urls"},
|
||||
},
|
||||
{
|
||||
Key: NodeTypeSystemSum,
|
||||
Name: "工作流内置节点-保存结果",
|
||||
Group: NodeGroupSystem,
|
||||
Sort: 7,
|
||||
},
|
||||
}
|
||||
|
||||
// ===================== 缓存map & 工具函数 =====================
|
||||
var (
|
||||
nodeTypeMetaMap map[NodeType]NodeTypeMeta
|
||||
nodeGroupMap map[NodeGroup]NodeGroupMeta
|
||||
)
|
||||
|
||||
func init() {
|
||||
// 初始化分组缓存
|
||||
nodeGroupMap = make(map[NodeGroup]NodeGroupMeta, len(NodeGroupMetaList))
|
||||
for _, meta := range NodeGroupMetaList {
|
||||
nodeGroupMap[meta.Key] = meta
|
||||
}
|
||||
|
||||
// 初始化节点缓存
|
||||
nodeTypeMetaMap = make(map[NodeType]NodeTypeMeta, len(NodeTypeMetaList))
|
||||
for _, meta := range NodeTypeMetaList {
|
||||
nodeTypeMetaMap[meta.Key] = meta
|
||||
}
|
||||
}
|
||||
|
||||
// GetNodeTypeMeta 根据节点类型获取元信息
|
||||
func GetNodeTypeMeta(typ NodeType) (NodeTypeMeta, bool) {
|
||||
meta, ok := nodeTypeMetaMap[typ]
|
||||
return meta, ok
|
||||
}
|
||||
|
||||
// GetNodeTypeName 快速获取节点中文名称,不存在返回原始key
|
||||
func GetNodeTypeName(typ NodeType) string {
|
||||
meta, ok := nodeTypeMetaMap[typ]
|
||||
if !ok {
|
||||
return string(typ)
|
||||
}
|
||||
return meta.Name
|
||||
}
|
||||
|
||||
// GetNodeGroupMeta 根据分组标识获取分组元信息
|
||||
func GetNodeGroupMeta(g NodeGroup) (NodeGroupMeta, bool) {
|
||||
meta, ok := nodeGroupMap[g]
|
||||
return meta, ok
|
||||
}
|
||||
|
||||
// GetNodeGroupName 快速获取分组中文名称
|
||||
func GetNodeGroupName(g NodeGroup) string {
|
||||
meta, ok := nodeGroupMap[g]
|
||||
if !ok {
|
||||
return string(g)
|
||||
}
|
||||
return meta.Name
|
||||
}
|
||||
|
||||
// GetAllNodeTypeMeta 返回全部节点元数据副本
|
||||
func GetAllNodeTypeMeta() []NodeTypeMeta {
|
||||
list := make([]NodeTypeMeta, len(NodeTypeMetaList))
|
||||
copy(list, NodeTypeMetaList)
|
||||
return list
|
||||
}
|
||||
|
||||
// GetNodeGroupTree 获取【分组+节点】树形列表,完整所有节点
|
||||
func GetNodeGroupTree() []NodeGroupTree {
|
||||
return getFilteredNodeTree(nil)
|
||||
}
|
||||
|
||||
// GetFilterNodeTree 根据指定分组过滤节点树形结构
|
||||
// groups: 需要展示的分组key列表,传入nil返回全部
|
||||
func GetFilterNodeTree(groups []NodeGroup) []NodeGroupTree {
|
||||
return getFilteredNodeTree(groups)
|
||||
}
|
||||
|
||||
// getFilteredNodeTree 内部通用树形构建逻辑
|
||||
func getFilteredNodeTree(filterGroups []NodeGroup) []NodeGroupTree {
|
||||
// 构建分组过滤集合
|
||||
filterSet := make(map[NodeGroup]bool)
|
||||
for _, g := range filterGroups {
|
||||
filterSet[g] = true
|
||||
}
|
||||
|
||||
groupNodeMap := make(map[NodeGroup][]NodeTypeMeta)
|
||||
for _, node := range NodeTypeMetaList {
|
||||
// 有过滤条件 && 当前分组不在过滤列表,则跳过
|
||||
if len(filterSet) > 0 && !filterSet[node.Group] {
|
||||
continue
|
||||
}
|
||||
groupNodeMap[node.Group] = append(groupNodeMap[node.Group], node)
|
||||
}
|
||||
|
||||
var tree []NodeGroupTree
|
||||
// 按定义顺序组装分组
|
||||
for _, gMeta := range NodeGroupMetaList {
|
||||
// 如果开启过滤,跳过不在筛选列表中的分组
|
||||
if len(filterSet) > 0 && !filterSet[gMeta.Key] {
|
||||
continue
|
||||
}
|
||||
nodes := groupNodeMap[gMeta.Key]
|
||||
if len(nodes) == 0 {
|
||||
continue
|
||||
}
|
||||
tree = append(tree, NodeGroupTree{
|
||||
Group: gMeta,
|
||||
Nodes: nodes,
|
||||
})
|
||||
}
|
||||
return tree
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user