- 新增 ActivePull 实体、DAO、DTO 及 Service,支持主动拉取任务管理 - 新增 ComposeCallback、VideoCallback、HttpNodeCallback 多类型回调接口 - FlowExecution 增加 NodeGroupId 和 TotalTokens 字段,支持节点组追踪与 Token 统计 - ExecutedNodes 结构由字符串列表改为包含执行状态的节点对象列表 - 重构回调通知机制,统一 Notify 函数调用 - 优化输出项类型判断逻辑,新增文件类型标识
223 lines
5.4 KiB
Go
223 lines
5.4 KiB
Go
package flow
|
|
|
|
import (
|
|
"ai-agent/workflow/consts/flow"
|
|
"ai-agent/workflow/consts/node"
|
|
flowDao "ai-agent/workflow/dao/flow"
|
|
flowDto "ai-agent/workflow/model/dto/flow"
|
|
"ai-agent/workflow/model/entity"
|
|
"ai-agent/workflow/service"
|
|
"context"
|
|
|
|
"gitea.com/red-future/common/beans"
|
|
"gitea.com/red-future/common/utils"
|
|
"github.com/gogf/gf/v2/frame/g"
|
|
"github.com/gogf/gf/v2/util/gconv"
|
|
)
|
|
|
|
var FlowUserService = &flowUserService{}
|
|
|
|
type flowUserService struct{}
|
|
|
|
func (s *flowUserService) Create(ctx context.Context, req *flowDto.CreateFlowUserReq) (res *flowDto.CreateFlowUserRes, err error) {
|
|
admin, err := service.UtilService.IsAdmin(ctx)
|
|
if err != nil {
|
|
return
|
|
}
|
|
req.NodeInputParams = ExtractFlowNodeFrom(req.FlowContent)
|
|
var id int64
|
|
if admin {
|
|
id, err = flowDao.FlowTemplateDao.Insert(ctx, &flowDto.CreateFlowTemplateReq{
|
|
FlowTemplateName: req.FlowName,
|
|
Description: req.Description,
|
|
FlowContent: req.FlowContent,
|
|
NodeInputParams: req.NodeInputParams,
|
|
Status: flow.FlowTemplateStatusEnable.Code(),
|
|
})
|
|
} else {
|
|
id, err = flowDao.FlowUserDao.Insert(ctx, req)
|
|
}
|
|
return &flowDto.CreateFlowUserRes{Id: id}, err
|
|
}
|
|
|
|
func (s *flowUserService) Update(ctx context.Context, req *flowDto.UpdateFlowUserReq) (err error) {
|
|
admin, err := service.UtilService.IsAdmin(ctx)
|
|
if err != nil {
|
|
return
|
|
}
|
|
req.NodeInputParams = ExtractFlowNodeFrom(req.FlowContent)
|
|
get, err := flowDao.FlowTemplateDao.Get(ctx, &flowDto.GetFlowTemplateReq{
|
|
Id: req.Id,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !g.IsEmpty(get) && !admin {
|
|
_, err = flowDao.FlowUserDao.Insert(ctx, &flowDto.CreateFlowUserReq{
|
|
FlowName: req.FlowName,
|
|
Description: req.Description,
|
|
FlowContent: req.FlowContent,
|
|
NodeInputParams: req.NodeInputParams,
|
|
SourceFlowTemplateId: get.Id,
|
|
})
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
if admin {
|
|
_, err = flowDao.FlowTemplateDao.Update(ctx, &flowDto.UpdateFlowTemplateReq{
|
|
Id: req.Id,
|
|
FlowTemplateName: req.FlowName,
|
|
Description: req.Description,
|
|
FlowContent: req.FlowContent,
|
|
NodeInputParams: req.NodeInputParams,
|
|
Status: flow.FlowTemplateStatusEnable.Code(),
|
|
})
|
|
} else {
|
|
_, err = flowDao.FlowUserDao.Update(ctx, req)
|
|
}
|
|
return
|
|
}
|
|
|
|
func ExtractFlowNodeFrom(flowContent *entity.FlowInfo) []*entity.FlowNode {
|
|
// 构建每个节点的上游节点映射
|
|
upstreamMap := make(map[string][]string)
|
|
for _, edge := range flowContent.Edges {
|
|
upstreamMap[edge.To] = append(upstreamMap[edge.To], edge.From)
|
|
}
|
|
|
|
// 同时更新 flowContent.Nodes 中的 DataMerge 节点
|
|
for i := range flowContent.Nodes {
|
|
n := &flowContent.Nodes[i]
|
|
// 对于 DataMerge 节点,自动根据边关系填充 InputSource
|
|
if n.NodeCode == node.NodeTypeDataMerge {
|
|
n.InputSource = nil
|
|
for _, fromId := range upstreamMap[n.Id] {
|
|
n.InputSource = append(n.InputSource, entity.FlowNodeInputSource{
|
|
NodeId: fromId,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
var flowNodes []*entity.FlowNode
|
|
for _, item := range flowContent.Nodes {
|
|
flowNodes = append(flowNodes, &item)
|
|
}
|
|
return flowNodes
|
|
}
|
|
|
|
func (s *flowUserService) Delete(ctx context.Context, req *flowDto.DeleteFlowUserReq) (err error) {
|
|
admin, err := service.UtilService.IsAdmin(ctx)
|
|
if err != nil {
|
|
return
|
|
}
|
|
if admin {
|
|
_, err = flowDao.FlowTemplateDao.Delete(ctx, &flowDto.DeleteFlowTemplateReq{
|
|
Id: req.Id,
|
|
})
|
|
} else {
|
|
_, err = flowDao.FlowUserDao.Delete(ctx, req)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *flowUserService) Get(ctx context.Context, req *flowDto.GetFlowUserReq) (res *flowDto.FlowUserVO, err error) {
|
|
|
|
var flowInfo *entity.FlowTemplate
|
|
flowInfo, err = flowDao.FlowTemplateDao.Get(ctx, &flowDto.GetFlowTemplateReq{
|
|
Id: req.Id,
|
|
})
|
|
if err != nil {
|
|
return
|
|
}
|
|
if flowInfo != nil {
|
|
res = new(flowDto.FlowUserVO)
|
|
res.FlowName = flowInfo.FlowTemplateName
|
|
err = gconv.Struct(flowInfo, res)
|
|
return
|
|
}
|
|
|
|
var flowUserInfo *entity.FlowUser
|
|
flowUserInfo, err = flowDao.FlowUserDao.Get(ctx, req)
|
|
if err != nil {
|
|
return
|
|
}
|
|
res = new(flowDto.FlowUserVO)
|
|
err = gconv.Struct(flowUserInfo, res)
|
|
return
|
|
}
|
|
|
|
func (s *flowUserService) List(ctx context.Context, req *flowDto.ListFlowUserReq) (res *flowDto.ListFlowRes, err error) {
|
|
admin, err := service.UtilService.IsAdmin(ctx)
|
|
if err != nil {
|
|
return
|
|
}
|
|
if admin {
|
|
var t int
|
|
var l []*entity.FlowTemplate
|
|
l, t, err = flowDao.FlowTemplateDao.List(ctx, &flowDto.ListFlowTemplateReq{
|
|
Keyword: req.Keyword,
|
|
Page: req.Page,
|
|
})
|
|
if err != nil {
|
|
return
|
|
}
|
|
r := &flowDto.ListFlowTemplateRes{
|
|
Total: t,
|
|
}
|
|
err = gconv.Struct(l, &r.List)
|
|
if err != nil {
|
|
return
|
|
}
|
|
res = &flowDto.ListFlowRes{
|
|
ListFlowUserRes: nil,
|
|
ListFlowTemplateRes: r,
|
|
IsAdmin: admin,
|
|
}
|
|
return
|
|
}
|
|
|
|
var t int
|
|
var l []*entity.FlowTemplate
|
|
l, t, err = flowDao.FlowTemplateDao.List(ctx, &flowDto.ListFlowTemplateReq{
|
|
Keyword: req.Keyword,
|
|
Page: req.Page,
|
|
})
|
|
if err != nil {
|
|
return
|
|
}
|
|
r := &flowDto.ListFlowTemplateRes{
|
|
Total: t,
|
|
}
|
|
err = gconv.Struct(l, &r.List)
|
|
if err != nil {
|
|
return
|
|
}
|
|
var user *beans.User
|
|
user, err = utils.GetUserInfo(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
req.Creator = user.UserName
|
|
list, total, err := flowDao.FlowUserDao.List(ctx, req)
|
|
if err != nil {
|
|
return
|
|
}
|
|
re := &flowDto.ListFlowUserRes{
|
|
Total: total,
|
|
}
|
|
err = gconv.Struct(list, &re.List)
|
|
if err != nil {
|
|
return
|
|
}
|
|
res = &flowDto.ListFlowRes{
|
|
ListFlowUserRes: re,
|
|
ListFlowTemplateRes: r,
|
|
IsAdmin: admin,
|
|
}
|
|
|
|
return
|
|
}
|