package themes_handler import ( "fmt" "log" "net/http" "strconv" "strings" "autolibrary.top/webserver/backend/models/themes_model" "github.com/gin-gonic/gin" ) func (h *Handler) GetFeaturedThemes(c *gin.Context) { limitStr := c.Query("limit") limit := 6 if limitStr != "" { if v, err := strconv.Atoi(limitStr); err == nil && v > 0 && v <= 20 { limit = v } } var themes []themes_model.Theme result := h.DB. Where("status = ?", themes_model.ThemeApproved). Order("download_count DESC"). Limit(limit). Find(&themes) if result.Error != nil { log.Printf("[E] GET > occur an error when get featured themes: %v", result.Error) c.JSON(http.StatusInternalServerError, gin.H{ "code": http.StatusInternalServerError, "msg": "GET > occur an error when get featured themes", "data": nil, }) return } for i := range themes { themes[i].Author = h.Users.ResolveAuthor(themes[i].UserID, themes[i].Author) themes[i].Verified = h.Users.IsVerified(themes[i].UserID) } log.Printf("[I] GET > get featured themes (limit=%d) successful", limit) c.JSON(http.StatusOK, gin.H{ "code": http.StatusOK, "msg": "GET > get featured themes successful", "data": themes, }) } // GET /api/themes?page=1&per_page=9&need_theme=&tags=&search=&sort=popular func (h *Handler) GetThemes(c *gin.Context) { pageStr := c.Query("page") perPageStr := c.Query("per_page") needTheme := c.Query("need_theme") tagsStr := c.Query("tags") search := c.Query("search") sort := c.Query("sort") if pageStr == "" { pageStr = "1" } if perPageStr == "" { perPageStr = "9" } if sort == "" { sort = "popular" } page, err := strconv.Atoi(pageStr) if err != nil || page <= 0 { page = 1 } perPage, err := strconv.Atoi(perPageStr) if err != nil || perPage <= 0 || perPage > 50 { perPage = 9 } offset := (page - 1) * perPage query := h.DB.Where("status = ?", themes_model.ThemeApproved) if needTheme != "" { if needTheme == "both" { query = query.Where("need_theme = ?", "both") } else if needTheme == "dark" || needTheme == "light" { query = query.Where("need_theme = ? OR need_theme = ?", needTheme, "both") } } if tagsStr != "" { tags := strings.Split(tagsStr, ",") for _, tag := range tags { tag = strings.TrimSpace(tag) if tag != "" { query = query.Where("tags LIKE ?", fmt.Sprintf("%%%s%%", tag)) } } } if search != "" { like := fmt.Sprintf("%%%s%%", search) query = query.Where("name LIKE ? OR brief LIKE ? OR author LIKE ?", like, like, like) } switch sort { case "newest": query = query.Order("created_at DESC") case "name": query = query.Order("name ASC") default: // popular query = query.Order("download_count DESC") } var total int64 if result := query.Model(&themes_model.Theme{}).Count(&total); result.Error != nil { log.Printf("[E] GET > occur an error when count themes: %v", result.Error) c.JSON(http.StatusInternalServerError, gin.H{ "code": http.StatusInternalServerError, "msg": "GET > occur an error when get themes", "data": nil, }) return } var themes []themes_model.Theme result := query.Limit(perPage).Offset(offset).Find(&themes) if result.Error != nil { log.Printf("[E] GET > occur an error when get themes (page=%d, per_page=%d): %v", page, perPage, result.Error) c.JSON(http.StatusInternalServerError, gin.H{ "code": http.StatusInternalServerError, "msg": "GET > occur an error when get themes", "data": nil, }) return } for i := range themes { themes[i].Author = h.Users.ResolveAuthor(themes[i].UserID, themes[i].Author) themes[i].Verified = h.Users.IsVerified(themes[i].UserID) } totalPages := int(total) / perPage if int(total)%perPage != 0 { totalPages++ } log.Printf("[I] GET > get themes (page=%d, per_page=%d, total=%d) successful", page, perPage, total) c.JSON(http.StatusOK, gin.H{ "code": http.StatusOK, "msg": "GET > get themes successful", "data": gin.H{ "themes": themes, "meta": gin.H{ "page": page, "per_page": perPage, "total": total, "total_pages": totalPages, "has_next": page < totalPages, }, }, }) } // GET /api/themes/:id func (h *Handler) GetThemeByID(c *gin.Context) { id, err := strconv.Atoi(c.Param("id")) if err != nil { log.Printf("[E] GET > try to get theme, but got invalid id: '%s'", c.Param("id")) c.JSON(http.StatusBadRequest, gin.H{ "code": http.StatusBadRequest, "msg": "GET > invalid id", "data": nil, }) return } var theme themes_model.Theme result := h.DB.Where("status = ?", themes_model.ThemeApproved).First(&theme, id) if result.Error != nil { log.Printf("[E] GET > theme (id=%d) can not found: %v", id, result.Error) c.JSON(http.StatusNotFound, gin.H{ "code": http.StatusNotFound, "msg": "GET > theme not found", "data": nil, }) return } theme.Author = h.Users.ResolveAuthor(theme.UserID, theme.Author) theme.Verified = h.Users.IsVerified(theme.UserID) log.Printf("[I] GET > get theme (id=%d) successful", id) c.JSON(http.StatusOK, gin.H{ "code": http.StatusOK, "msg": "GET > get theme successful", "data": theme, }) } // GET /api/themes/:id/download func (h *Handler) GetUserThemes(c *gin.Context) { userID, _ := c.Get("user_id") var themes []themes_model.Theme result := h.DB. Where("user_id = ?", userID.(string)). Order("created_at DESC"). Find(&themes) if result.Error != nil { log.Printf("[E] GET > occur an error when get user themes: %v", result.Error) c.JSON(http.StatusInternalServerError, gin.H{"code": http.StatusInternalServerError, "msg": "获取用户主题失败", "data": nil}) return } for i := range themes { themes[i].Author = h.Users.ResolveAuthor(themes[i].UserID, themes[i].Author) themes[i].Verified = h.Users.IsVerified(themes[i].UserID) } log.Printf("[I] GET > get user themes (user_id=%s, count=%d) successful", userID.(string), len(themes)) c.JSON(http.StatusOK, gin.H{"code": http.StatusOK, "msg": "GET > get user themes successful", "data": themes}) }