You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
302 lines
9.0 KiB
302 lines
9.0 KiB
1 month ago
|
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))
|
||
|
}
|