package controller import ( reponse "gofaster/internal/shared/model" "gofaster/internal/workflow/model" "gofaster/internal/workflow/service" "net/http" "strconv" "github.com/gin-gonic/gin" ) type WorkflowController struct { service *service.WorkflowService engine *service.WorkflowEngine } func NewWorkflowController(service *service.WorkflowService, engine *service.WorkflowEngine) *WorkflowController { return &WorkflowController{ service: service, engine: engine, } } // CreateWorkflow 创建新工作流 func (c *WorkflowController) CreateWorkflow(ctx *gin.Context) { var workflow model.Workflow if err := ctx.ShouldBindJSON(&workflow); err != nil { ctx.JSON(http.StatusBadRequest, reponse.NewErrorResponse("无效的请求数据")) return } if err := c.service.CreateWorkflow(&workflow); err != nil { ctx.JSON(http.StatusInternalServerError, reponse.NewErrorResponse("创建工作流失败")) return } ctx.JSON(http.StatusCreated, reponse.NewSuccessResponse(workflow)) } // GetWorkflow 获取工作流详情 func (c *WorkflowController) GetWorkflow(ctx *gin.Context) { id, err := strconv.ParseUint(ctx.Param("id"), 10, 32) if err != nil { ctx.JSON(http.StatusBadRequest, reponse.NewErrorResponse("无效的工作流ID")) return } workflow, err := c.service.GetWorkflowByID(uint(id)) if err != nil { ctx.JSON(http.StatusNotFound, reponse.NewErrorResponse("工作流不存在")) return } ctx.JSON(http.StatusOK, reponse.NewSuccessResponse(workflow)) } // ListWorkflows 列出工作流 func (c *WorkflowController) ListWorkflows(ctx *gin.Context) { page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(ctx.DefaultQuery("pageSize", "10")) workflows, total, err := c.service.ListWorkflows(page, pageSize) if err != nil { ctx.JSON(http.StatusInternalServerError, reponse.NewErrorResponse("获取工作流列表失败")) return } ctx.JSON(http.StatusOK, reponse.NewPaginationResponse(workflows, total, page, pageSize)) } // UpdateWorkflow 更新工作流 func (c *WorkflowController) UpdateWorkflow(ctx *gin.Context) { id, err := strconv.ParseUint(ctx.Param("id"), 10, 32) if err != nil { ctx.JSON(http.StatusBadRequest, reponse.NewErrorResponse("无效的工作流ID")) return } var workflow model.Workflow if err := ctx.ShouldBindJSON(&workflow); err != nil { ctx.JSON(http.StatusBadRequest, reponse.NewErrorResponse("无效的请求数据")) return } workflow.ID = uint(id) if err := c.service.UpdateWorkflow(&workflow); err != nil { ctx.JSON(http.StatusInternalServerError, reponse.NewErrorResponse("更新工作流失败")) return } ctx.JSON(http.StatusOK, reponse.NewSuccessResponse(workflow)) } // DeleteWorkflow 删除工作流 func (c *WorkflowController) DeleteWorkflow(ctx *gin.Context) { id, err := strconv.ParseUint(ctx.Param("id"), 10, 32) if err != nil { ctx.JSON(http.StatusBadRequest, reponse.NewErrorResponse("无效的工作流ID")) return } if err := c.service.DeleteWorkflow(uint(id)); err != nil { ctx.JSON(http.StatusInternalServerError, reponse.NewErrorResponse("删除工作流失败")) return } ctx.JSON(http.StatusNoContent, nil) } // AddNode 添加工作流节点 func (c *WorkflowController) AddNode(ctx *gin.Context) { workflowID, err := strconv.ParseUint(ctx.Param("id"), 10, 32) if err != nil { ctx.JSON(http.StatusBadRequest, reponse.NewErrorResponse("无效的工作流ID")) return } var node model.WorkflowNode if err := ctx.ShouldBindJSON(&node); err != nil { ctx.JSON(http.StatusBadRequest, reponse.NewErrorResponse("无效的节点数据")) return } node.WorkflowID = uint(workflowID) if err := c.service.AddNode(&node); err != nil { ctx.JSON(http.StatusInternalServerError, reponse.NewErrorResponse("添加节点失败")) return } ctx.JSON(http.StatusCreated, reponse.NewSuccessResponse(node)) } // UpdateNode 更新工作流节点 func (c *WorkflowController) UpdateNode(ctx *gin.Context) { nodeID, err := strconv.ParseUint(ctx.Param("node_id"), 10, 32) if err != nil { ctx.JSON(http.StatusBadRequest, reponse.NewErrorResponse("无效的节点ID")) return } var node model.WorkflowNode if err := ctx.ShouldBindJSON(&node); err != nil { ctx.JSON(http.StatusBadRequest, reponse.NewErrorResponse("无效的节点数据")) return } node.ID = uint(nodeID) if err := c.service.UpdateNode(&node); err != nil { ctx.JSON(http.StatusInternalServerError, reponse.NewErrorResponse("更新节点失败")) return } ctx.JSON(http.StatusOK, reponse.NewSuccessResponse(node)) } // DeleteNode 删除工作流节点 func (c *WorkflowController) DeleteNode(ctx *gin.Context) { nodeID, err := strconv.ParseUint(ctx.Param("node_id"), 10, 32) if err != nil { ctx.JSON(http.StatusBadRequest, reponse.NewErrorResponse("无效的节点ID")) return } if err := c.service.DeleteNode(uint(nodeID)); err != nil { ctx.JSON(http.StatusInternalServerError, reponse.NewErrorResponse("删除节点失败")) return } ctx.JSON(http.StatusNoContent, nil) } // StartWorkflow 启动工作流实例 func (c *WorkflowController) StartWorkflow(ctx *gin.Context) { var req struct { WorkflowID uint `json:"workflow_id" binding:"required"` Data map[string]interface{} `json:"data"` } if err := ctx.ShouldBindJSON(&req); err != nil { ctx.JSON(http.StatusBadRequest, reponse.NewErrorResponse("无效的请求数据")) return } instance, err := c.engine.StartWorkflow(req.WorkflowID, req.Data) if err != nil { ctx.JSON(http.StatusInternalServerError, reponse.NewErrorResponse("启动工作流失败")) return } ctx.JSON(http.StatusCreated, reponse.NewSuccessResponse(instance)) } // ListInstances 列出工作流实例 func (c *WorkflowController) ListInstances(ctx *gin.Context) { workflowID, _ := strconv.ParseUint(ctx.Query("workflow_id"), 10, 32) page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(ctx.DefaultQuery("pageSize", "10")) instances, total, err := c.service.ListInstances(uint(workflowID), page, pageSize) if err != nil { ctx.JSON(http.StatusInternalServerError, reponse.NewErrorResponse("获取实例列表失败")) return } ctx.JSON(http.StatusOK, reponse.NewPaginationResponse(instances, total, page, pageSize)) } // GetInstance 获取工作流实例详情 func (c *WorkflowController) GetInstance(ctx *gin.Context) { id, err := strconv.ParseUint(ctx.Param("id"), 10, 32) if err != nil { ctx.JSON(http.StatusBadRequest, reponse.NewErrorResponse("无效的实例ID")) return } instance, err := c.service.GetInstanceByID(uint(id)) if err != nil { ctx.JSON(http.StatusNotFound, reponse.NewErrorResponse("工作流实例不存在")) return } ctx.JSON(http.StatusOK, reponse.NewSuccessResponse(instance)) } // CancelInstance 取消工作流实例 func (c *WorkflowController) CancelInstance(ctx *gin.Context) { id, err := strconv.ParseUint(ctx.Param("id"), 10, 32) if err != nil { ctx.JSON(http.StatusBadRequest, reponse.NewErrorResponse("无效的实例ID")) return } if err := c.service.CancelInstance(uint(id)); err != nil { ctx.JSON(http.StatusInternalServerError, reponse.NewErrorResponse("取消实例失败")) return } ctx.JSON(http.StatusOK, reponse.NewSuccessResponse(nil)) } // ListTasks 列出实例任务 func (c *WorkflowController) ListTasks(ctx *gin.Context) { instanceID, err := strconv.ParseUint(ctx.Param("id"), 10, 32) if err != nil { ctx.JSON(http.StatusBadRequest, reponse.NewErrorResponse("无效的实例ID")) return } tasks, err := c.service.ListTasksByInstance(uint(instanceID)) if err != nil { ctx.JSON(http.StatusInternalServerError, reponse.NewErrorResponse("获取任务列表失败")) return } ctx.JSON(http.StatusOK, reponse.NewSuccessResponse(tasks)) } // ProcessTask 处理工作流任务 func (c *WorkflowController) ProcessTask(ctx *gin.Context) { taskID, err := strconv.ParseUint(ctx.Param("task_id"), 10, 32) if err != nil { ctx.JSON(http.StatusBadRequest, reponse.NewErrorResponse("无效的任务ID")) return } var req struct { UserID uint `json:"user_id" binding:"required"` Result map[string]interface{} `json:"result"` } if err := ctx.ShouldBindJSON(&req); err != nil { ctx.JSON(http.StatusBadRequest, reponse.NewErrorResponse("无效的请求数据")) return } if err := c.engine.ProcessTask(uint(taskID), req.UserID, req.Result); err != nil { ctx.JSON(http.StatusInternalServerError, reponse.NewErrorResponse("处理任务失败")) return } ctx.JSON(http.StatusOK, reponse.NewSuccessResponse(nil)) } // GetUserTasks 获取用户任务 func (c *WorkflowController) GetUserTasks(ctx *gin.Context) { userID, err := strconv.ParseUint(ctx.Query("user_id"), 10, 32) if err != nil { ctx.JSON(http.StatusBadRequest, reponse.NewErrorResponse("无效的用户ID")) return } status := ctx.Query("status") tasks, err := c.service.GetUserTasks(uint(userID), status) if err != nil { ctx.JSON(http.StatusInternalServerError, reponse.NewErrorResponse("获取用户任务失败")) return } ctx.JSON(http.StatusOK, reponse.NewSuccessResponse(tasks)) }