package article import ( "fmt" "net/http" "toutoukan/init/databaseInit" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // ArticleOption 文评选项结构 type ArticleOption struct { ID int64 `json:"id"` // 选项ID Name string `json:"name"` // 选项名称 Votes int `json:"votes"` // 该选项的投票数 IsVotedByUser bool `json:"is_voted"` // 当前用户是否投了该选项 } // ArticleResponse 单个文评的响应结构 type ArticleResponse struct { ID int64 `json:"文评ID"` // 文评唯一ID Title string `json:"文评标题"` // 文评标题 VoteType string `json:"投票类型"` // 投票类型 TotalVoters int `json:"总投票人数"` // 总投票人数 EndTime string `json:"结束时间"` // 结束时间 IsEnded bool `json:"是否结束"` // 是否结束 PublisherID string `json:"发布者ID"` // 发布者ID CreateTime string `json:"创建时间"` // 创建时间 Options []ArticleOption `json:"选项"` // 按顺序排列的选项列表 UserHasVoted bool `json:"用户是否已投票"` // 当前用户是否投过票 VotedOptionID *int64 `json:"用户投票的选项ID"` // 若已投票,记录选项ID(未投票为null) } type UserReq struct { Uid string `json:"uid"` } // ArticleListget 获取所有文评及选项信息(包含用户投票状态) func ArticleListget(c *gin.Context) { var req UserReq // 1. 解析并验证请求参数 if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": "参数解析失败", "detail": err.Error(), }) return } // 2. 查询所有文评 var articles []struct { ArticleID int64 `gorm:"column:articleId"` Title string `gorm:"column:title"` VoteType string `gorm:"column:vote_type"` TotalVotersNum int `gorm:"column:total_voters_num"` EndTime string `gorm:"column:end_time"` IsEnded bool `gorm:"column:is_ended"` PublishUserID string `gorm:"column:publish_user_id"` CreateTime string `gorm:"column:create_time"` } if err := databaseInit.UserDB.Table("article_list"). Select("articleId, title, vote_type, total_voters_num, end_time, is_ended, publish_user_id, create_time"). Find(&articles).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": "查询文评失败: " + err.Error(), }) return } fmt.Println("所有文评列表:", articles) // 3. 构建结果映射 result := make(map[string]interface{}) // 4. 逐个处理文评 for _, article := range articles { // 4.1 查询当前文评的选项 var options []struct { ID int64 `gorm:"column:id"` OptionName string `gorm:"column:option_content"` VoteCount int `gorm:"column:option_votes_num"` SortOrder int `gorm:"column:sort_order"` } if err := databaseInit.UserDB.Table("article_options"). Where("vote_article_id = ?", article.ArticleID). Select("id, option_content, option_votes_num, sort_order"). Order("sort_order ASC"). Find(&options).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "error": "查询文评选项失败: " + err.Error(), }) return } // 4.2 查询当前用户对该文评的投票记录 var userVote struct { OptionID int64 `gorm:"column:option_id"` } voteErr := databaseInit.UserDB.Table("user_votes"). Where("user_id = ? AND vote_article_id = ?", req.Uid, article.ArticleID). First(&userVote).Error // 标记用户是否投票及投票的选项ID userHasVoted := false var votedOptionID *int64 = nil if voteErr == nil { userHasVoted = true votedOptionID = &userVote.OptionID } else if voteErr != gorm.ErrRecordNotFound { // 处理查询错误(非"未找到"的错误) c.JSON(http.StatusInternalServerError, gin.H{ "error": "查询用户投票记录失败: " + voteErr.Error(), }) return } // 4.3 格式化选项数据(标记用户是否投了该选项) var optionList []ArticleOption for _, opt := range options { // 检查当前选项是否是用户投票的选项 isVoted := userHasVoted && (opt.ID == *votedOptionID) optionList = append(optionList, ArticleOption{ ID: opt.ID, Name: opt.OptionName, Votes: opt.VoteCount, IsVotedByUser: isVoted, // 标记当前用户是否投了这个选项 }) } // 4.4 组装单个文评的响应数据 articleData := ArticleResponse{ ID: article.ArticleID, Title: article.Title, VoteType: article.VoteType, TotalVoters: article.TotalVotersNum, EndTime: article.EndTime, IsEnded: article.IsEnded, PublisherID: article.PublishUserID, CreateTime: article.CreateTime, Options: optionList, UserHasVoted: userHasVoted, // 整体标记用户是否投过票 VotedOptionID: votedOptionID, // 记录用户投票的选项ID(未投票则为null) } // 4.5 加入结果集 result[article.Title] = articleData } c.JSON(http.StatusOK, result) }