更新投票功能
This commit is contained in:
137
controllers/article/createarticle.go
Normal file
137
controllers/article/createarticle.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package article
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
"toutoukan/init/databaseInit"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// OptionItem 选项子结构
|
||||
type OptionItem struct {
|
||||
Content string `json:"content" binding:"required,min=1,max=200"` // 选项内容
|
||||
SortOrder int `json:"sort_order" binding:"required,min=0"` // 排序值
|
||||
}
|
||||
|
||||
// CreateArticleRequest 创建文章的请求参数结构
|
||||
type CreateArticleRequest struct {
|
||||
PublishUserID string `json:"publish_user_id" binding:"required,min=1,max=40"`
|
||||
Title string `json:"title" binding:"required,min=1,max=255"`
|
||||
VoteType string `json:"vote_type" binding:"required,min=1,max=60"`
|
||||
EndTime time.Time `json:"end_time" binding:"required"`
|
||||
Options []OptionItem `json:"options" binding:"required,min=1,max=3"`
|
||||
}
|
||||
|
||||
// 数据库文章记录结构体(与表结构完全对应)
|
||||
type ArticleList struct {
|
||||
ArticleID int64 `gorm:"column:articleId;primaryKey;autoIncrement"` // 明确主键和自增
|
||||
PublishUserID string `gorm:"column:publish_user_id"`
|
||||
Title string `gorm:"column:title"`
|
||||
VoteType string `gorm:"column:vote_type"`
|
||||
EndTime time.Time `gorm:"column:end_time"`
|
||||
IsEnded bool `gorm:"column:is_ended"`
|
||||
TotalVotersNum int `gorm:"column:total_voters_num"`
|
||||
CreateTime time.Time `gorm:"column:create_time"`
|
||||
}
|
||||
|
||||
// 自定义表名(如果结构体名与表名不一致)
|
||||
func (ArticleList) TableName() string {
|
||||
return "article_list"
|
||||
}
|
||||
|
||||
// CreateArticle 创建文章(包含选项)
|
||||
func CreateArticle(c *gin.Context) {
|
||||
var req CreateArticleRequest
|
||||
|
||||
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. 创建文章主记录
|
||||
newArticle := ArticleList{
|
||||
PublishUserID: req.PublishUserID,
|
||||
Title: req.Title,
|
||||
VoteType: req.VoteType,
|
||||
EndTime: req.EndTime,
|
||||
IsEnded: false,
|
||||
TotalVotersNum: 0,
|
||||
CreateTime: time.Now(),
|
||||
}
|
||||
|
||||
// 插入文章并获取ID(使用GORM的Create方法,自动填充自增ID)
|
||||
if err := tx.Create(&newArticle).Error; err != nil {
|
||||
tx.Rollback()
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "创建文章失败: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// 验证文章ID是否有效(必须大于0)
|
||||
if newArticle.ArticleID <= 0 {
|
||||
tx.Rollback()
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "无法获取文章ID,创建失败"})
|
||||
return
|
||||
}
|
||||
|
||||
// 2. 批量创建选项(确保vote_article_id正确关联)
|
||||
var options []map[string]interface{}
|
||||
for _, opt := range req.Options {
|
||||
options = append(options, map[string]interface{}{
|
||||
"vote_article_id": newArticle.ArticleID, // 使用刚创建的文章ID
|
||||
"option_content": opt.Content,
|
||||
"option_votes_num": 0,
|
||||
"sort_order": opt.SortOrder,
|
||||
})
|
||||
}
|
||||
|
||||
// 插入选项前先验证文章ID是否存在(额外保险)
|
||||
var count int64
|
||||
if err := tx.Model(&ArticleList{}).Where("articleId = ?", newArticle.ArticleID).Count(&count).Error; err != nil {
|
||||
tx.Rollback()
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "验证文章ID失败: " + err.Error()})
|
||||
return
|
||||
}
|
||||
if count == 0 {
|
||||
tx.Rollback()
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "文章ID不存在,外键约束失败"})
|
||||
return
|
||||
}
|
||||
|
||||
// 批量插入选项
|
||||
if err := tx.Table("article_options").CreateInBatches(options, len(options)).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{
|
||||
"article_id": newArticle.ArticleID,
|
||||
"option_count": len(req.Options),
|
||||
},
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user