package controller import ( "encoding/json" "net/http" "strconv" "ezops/model" "github.com/gin-gonic/gin" ) // 应用发布(Release)相关 handler,与 PipelineHandler 共享 receiver,按应用发布域从 pipeline.go 拆分 // Logan.Li // ListReleases 获取发布列表 // @Summary 获取发布列表 // @Description 获取所有应用发布列表 // @Tags 应用发布 // @Produce json // @Security Bearer // @Param page query int false "页码" // @Param page_size query int false "每页数量" // @Success 200 {object} model.Response{data=model.ListResponse} // @Router /releases [get] func (h *PipelineHandler) ListReleases(c *gin.Context) { var query model.PageQuery c.ShouldBindQuery(&query) var total int64 h.db.Model(&model.AppRelease{}).Count(&total) var releases []model.AppRelease h.db.Order("created_at DESC"). Offset(query.GetOffset()). Limit(query.GetLimit()). Find(&releases) c.JSON(http.StatusOK, model.Response{ Code: 200, Message: "success", Data: model.ListResponse{ List: releases, Total: total, }, }) } // CreateRelease 创建发布 // @Summary 创建发布 // @Description 创建新应用发布 // @Tags 应用发布 // @Accept json // @Produce json // @Security Bearer // @Param request body model.CreateAppReleaseRequest true "创建请求" // @Success 200 {object} model.Response{data=model.AppRelease} // @Router /releases [post] func (h *PipelineHandler) CreateRelease(c *gin.Context) { var req model.CreateAppReleaseRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, model.Response{ Code: 400, Message: "请求参数错误: " + err.Error(), }) return } release := model.AppRelease{ PipelineID: req.PipelineID, PipelineRunID: req.PipelineRunID, AppName: req.AppName, Version: req.Version, Environment: req.Environment, DeployType: req.DeployType, Status: "pending", CommitID: req.CommitID, CommitMsg: req.CommitMsg, ImageTag: req.ImageTag, K8sClusterID: req.K8sClusterID, K8sNamespace: req.K8sNamespace, Servers: "[]", Description: req.Description, } if req.DeployType == "" { release.DeployType = "server" } if len(req.Servers) > 0 { data, _ := json.Marshal(req.Servers) release.Servers = string(data) } if err := h.db.Create(&release).Error; err != nil { c.JSON(http.StatusInternalServerError, model.Response{ Code: 500, Message: "创建失败", }) return } c.JSON(http.StatusOK, model.Response{ Code: 200, Message: "创建成功", Data: release, }) } // ApproveRelease 审批发布 // @Summary 审批发布 // @Description 审批应用发布 // @Tags 应用发布 // @Produce json // @Security Bearer // @Param id path int true "发布ID" // @Success 200 {object} model.Response{data=model.AppRelease} // @Router /releases/{id}/approve [post] func (h *PipelineHandler) ApproveRelease(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) var release model.AppRelease if err := h.db.First(&release, id).Error; err != nil { c.JSON(http.StatusNotFound, model.Response{ Code: 404, Message: "发布不存在", }) return } release.Status = "approved" // release.Approver = middleware.GetUsername(c) // now := time.Now() // release.ApprovedAt = &now if err := h.db.Save(&release).Error; err != nil { c.JSON(http.StatusInternalServerError, model.Response{ Code: 500, Message: "审批失败", }) return } c.JSON(http.StatusOK, model.Response{ Code: 200, Message: "审批成功", Data: release, }) } // DeployRelease 部署发布 // @Summary 部署发布 // @Description 部署应用发布 // @Tags 应用发布 // @Produce json // @Security Bearer // @Param id path int true "发布ID" // @Success 200 {object} model.Response{data=model.AppRelease} // @Router /releases/{id}/deploy [post] func (h *PipelineHandler) DeployRelease(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) var release model.AppRelease if err := h.db.First(&release, id).Error; err != nil { c.JSON(http.StatusNotFound, model.Response{ Code: 404, Message: "发布不存在", }) return } release.Status = "deploying" if err := h.db.Save(&release).Error; err != nil { c.JSON(http.StatusInternalServerError, model.Response{ Code: 500, Message: "部署失败", }) return } c.JSON(http.StatusOK, model.Response{ Code: 200, Message: "部署中", Data: release, }) } // RejectRelease 驳回发布申请 // Logan.Li func (h *PipelineHandler) RejectRelease(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) var release model.AppRelease if err := h.db.First(&release, id).Error; err != nil { c.JSON(http.StatusNotFound, model.Response{ Code: 404, Message: "发布不存在", }) return } if release.Status != "pending" { c.JSON(http.StatusBadRequest, model.Response{ Code: 400, Message: "仅待审批状态可驳回", }) return } release.Status = "rejected" if err := h.db.Save(&release).Error; err != nil { c.JSON(http.StatusInternalServerError, model.Response{ Code: 500, Message: "驳回失败", }) return } c.JSON(http.StatusOK, model.Response{ Code: 200, Message: "已驳回", Data: release, }) } // RollbackRelease 回滚发布 // @Summary 回滚发布 // @Description 回滚应用发布 // @Tags 应用发布 // @Produce json // @Security Bearer // @Param id path int true "发布ID" // @Success 200 {object} model.Response{data=model.AppRelease} // @Router /releases/{id}/rollback [post] func (h *PipelineHandler) RollbackRelease(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) var release model.AppRelease if err := h.db.First(&release, id).Error; err != nil { c.JSON(http.StatusNotFound, model.Response{ Code: 404, Message: "发布不存在", }) return } release.Status = "rolled_back" // now := time.Now() // release.RollbackAt = &now if err := h.db.Save(&release).Error; err != nil { c.JSON(http.StatusInternalServerError, model.Response{ Code: 500, Message: "回滚失败", }) return } c.JSON(http.StatusOK, model.Response{ Code: 200, Message: "回滚成功", Data: release, }) }