refactor: enhance AI workflow management with restore version and usage tracking features

This commit is contained in:
mlogclub
2026-07-25 18:19:59 +08:00
parent 1663db7f24
commit 05eb85167c
9 changed files with 126 additions and 191 deletions
+3 -1
View File
@@ -229,10 +229,10 @@ func registerDashboardAIAgentRoutes(group *gin.RouterGroup) {
}
func registerDashboardAIWorkflowRoutes(group *gin.RouterGroup) {
group.GET("/:id", dashboard.AIWorkflowGetBy)
group.POST("/create", dashboard.AIWorkflowPostCreate)
group.POST("/update", dashboard.AIWorkflowPostUpdate)
group.POST("/delete", dashboard.AIWorkflowPostDelete)
group.POST("/restore-version", dashboard.AIWorkflowPostRestoreVersion)
group.Any("/list", dashboard.AIWorkflowAnyList)
group.GET("/node-spec/list", dashboard.AIWorkflowGetNodeSpecList)
group.GET("/default-definition", dashboard.AIWorkflowGetDefaultDefinition)
@@ -242,6 +242,8 @@ func registerDashboardAIWorkflowRoutes(group *gin.RouterGroup) {
group.GET("/run/:id", dashboard.AIWorkflowGetRunBy)
group.Any("/version/list", dashboard.AIWorkflowAnyVersionList)
group.GET("/version/:id", dashboard.AIWorkflowGetVersionBy)
group.GET("/:id/usage", dashboard.AIWorkflowGetUsage)
group.GET("/:id", dashboard.AIWorkflowGetBy)
}
func registerDashboardAgentRunRoutes(group *gin.RouterGroup) {
@@ -99,6 +99,44 @@ func AIWorkflowPostDelete(ctx *gin.Context) {
httpx.WriteJSON(ctx, nil)
}
func AIWorkflowPostRestoreVersion(ctx *gin.Context) {
operator, err := services.AuthService.RequirePermission(ctx, constants.PermissionAIAgentUpdate)
if err != nil {
httpx.WriteJSON(ctx, err)
return
}
req := request.RestoreAIWorkflowVersionRequest{}
if err := params.ReadJSON(ctx, &req); err != nil {
httpx.WriteJSON(ctx, err)
return
}
if err := services.AIWorkflowService.RestoreVersion(req, operator); err != nil {
httpx.WriteJSON(ctx, err)
return
}
httpx.WriteJSON(ctx, nil)
}
func AIWorkflowGetUsage(ctx *gin.Context) {
id, ok := httpx.GetPathInt64(ctx, "id")
if !ok {
return
}
if _, err := services.AuthService.RequirePermission(ctx, constants.PermissionAIAgentView); err != nil {
httpx.WriteJSON(ctx, err)
return
}
items := services.AIWorkflowService.ListUsage(id)
ret := make([]response.AIWorkflowUsageResponse, 0, len(items))
for _, item := range items {
if item.Agent == nil || item.Version == nil {
continue
}
ret = append(ret, response.AIWorkflowUsageResponse{AIAgentID: item.Agent.ID, AIAgentName: item.Agent.Name, WorkflowVersionID: item.Binding.WorkflowVersionID, WorkflowVersion: item.Version.Version, Enabled: item.Binding.Enabled})
}
httpx.WriteJSON(ctx, ret)
}
func AIWorkflowGetNodeSpecList(ctx *gin.Context) {
if _, err := services.AuthService.RequirePermission(ctx, constants.PermissionAIAgentView); err != nil {
httpx.WriteJSON(ctx, err)
@@ -29,3 +29,8 @@ type PublishAIWorkflowRequest struct {
type AIWorkflowVersionListRequest struct {
WorkflowID int64 `json:"workflowId"`
}
type RestoreAIWorkflowVersionRequest struct {
WorkflowID int64 `json:"workflowId"`
WorkflowVersionID int64 `json:"workflowVersionId"`
}
@@ -47,6 +47,14 @@ type AIWorkflowTemplateResponse struct {
Definition dsl.Definition `json:"definition"`
}
type AIWorkflowUsageResponse struct {
AIAgentID int64 `json:"aiAgentId"`
AIAgentName string `json:"aiAgentName"`
WorkflowVersionID int64 `json:"workflowVersionId"`
WorkflowVersion int `json:"workflowVersion"`
Enabled bool `json:"enabled"`
}
type AIWorkflowNodeSpecResponse struct {
Type string `json:"type"`
Title string `json:"title"`
@@ -30,6 +30,14 @@ func (r *aiAgentWorkflowBindingRepository) FindEnabledByAgentID(db *gorm.DB, age
return ret
}
func (r *aiAgentWorkflowBindingRepository) FindByWorkflowID(db *gorm.DB, workflowID int64) []models.AIAgentWorkflowBinding {
ret := make([]models.AIAgentWorkflowBinding, 0)
if workflowID > 0 {
db.Where("workflow_id = ?", workflowID).Order("priority ASC, id ASC").Find(&ret)
}
return ret
}
func (r *aiAgentWorkflowBindingRepository) CountByWorkflowID(db *gorm.DB, workflowID int64) int64 {
var count int64
if workflowID > 0 {
+27
View File
@@ -48,6 +48,12 @@ type AIWorkflowTemplate struct {
Definition dsl.Definition
}
type AIWorkflowUsageItem struct {
Binding models.AIAgentWorkflowBinding
Agent *models.AIAgent
Version *models.AIWorkflowVersion
}
func (s *aiWorkflowService) Get(id int64) *models.AIWorkflow {
if id <= 0 {
return nil
@@ -263,6 +269,27 @@ func (s *aiWorkflowService) DeleteWorkflow(id int64, operator *dto.AuthPrincipal
})
}
func (s *aiWorkflowService) RestoreVersion(req request.RestoreAIWorkflowVersionRequest, operator *dto.AuthPrincipal) error {
if operator == nil {
return errorsx.UnauthorizedI18n("error.auth.expired")
}
workflow := s.Get(req.WorkflowID)
version := s.GetVersion(req.WorkflowVersionID)
if workflow == nil || version == nil || version.WorkflowID != workflow.ID {
return errorsx.InvalidParamI18n("error.e0002")
}
return repositories.AIWorkflowRepository.Updates(sqls.DB(), workflow.ID, map[string]any{"draft_definition": version.Definition, "update_user_id": operator.UserID, "update_user_name": operator.Username, "updated_at": time.Now()})
}
func (s *aiWorkflowService) ListUsage(workflowID int64) []AIWorkflowUsageItem {
bindings := repositories.AIAgentWorkflowBindingRepository.FindByWorkflowID(sqls.DB(), workflowID)
ret := make([]AIWorkflowUsageItem, 0, len(bindings))
for _, binding := range bindings {
ret = append(ret, AIWorkflowUsageItem{Binding: binding, Agent: repositories.AIAgentRepository.Get(sqls.DB(), binding.AIAgentID), Version: repositories.AIWorkflowVersionRepository.Get(sqls.DB(), binding.WorkflowVersionID)})
}
return ret
}
func (s *aiWorkflowService) PublishWorkflow(req request.PublishAIWorkflowRequest, operator *dto.AuthPrincipal) (*models.AIWorkflowVersion, error) {
if operator == nil {
return nil, errorsx.UnauthorizedI18n("error.auth.expired")