package article import ( "net/http" "toutoukan/init/databaseInit" "github.com/gin-gonic/gin" ) // DeleteArticleRequest 删除文章的请求参数 type DeleteArticleRequest struct { ArticleID int64 `json:"article_id" binding:"required,min=1"` // 要删除的文章ID } // DeleteArticle 删除文章(处理外键关联) func DeleteArticle(c *gin.Context) { var req DeleteArticleRequest // 解析请求参数 if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": "参数解析失败", "detail": err.Error(), }) return } // 开启事务(确保所有删除操作要么全部成功,要么全部失败) tx := databaseInit.UserDB.Begin() if tx.Error != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": "开启事务失败: " + tx.Error.Error(), }) return } defer func() { if r := recover(); r != nil { tx.Rollback() } }() // 步骤1:先删除用户投票记录(因为依赖文章ID和选项ID) if err := tx.Table("user_votes"). Where("vote_article_id = ?", req.ArticleID). Delete(nil).Error; err != nil { tx.Rollback() c.JSON(http.StatusInternalServerError, gin.H{ "error": "删除用户投票记录失败: " + err.Error(), }) return } // 步骤2:再删除文章选项(因为依赖文章ID) if err := tx.Table("article_options"). Where("vote_article_id = ?", req.ArticleID). Delete(nil).Error; err != nil { tx.Rollback() c.JSON(http.StatusInternalServerError, gin.H{ "error": "删除文章选项失败: " + err.Error(), }) return } // 步骤3:最后删除文章主记录 if err := tx.Table("article_list"). Where("articleId = ?", req.ArticleID). Delete(nil).Error; err != nil { tx.Rollback() c.JSON(http.StatusInternalServerError, gin.H{ "error": "删除文章失败: " + err.Error(), }) return } // 提交事务 if err := tx.Commit().Error; err != nil { tx.Rollback() c.JSON(http.StatusInternalServerError, gin.H{ "error": "提交删除操作失败: " + err.Error(), }) return } // 返回成功响应 c.JSON(http.StatusOK, gin.H{ "success": true, "message": "文章及关联数据已全部删除", "data": gin.H{ "deleted_article_id": req.ArticleID, }, }) }