Files
nl-blogs/server/handlers/video.go
2026-07-06 08:19:47 +08:00

359 lines
8.9 KiB
Go

package handlers
import (
"strconv"
"time"
"github.com/gin-gonic/gin"
"github.com/niangaodev/art-code/models"
"github.com/niangaodev/art-code/repositories"
"github.com/niangaodev/art-code/utils"
)
// ========== 公开 API ==========
// GetVideoCategories 获取视频分类列表
func GetVideoCategories(c *gin.Context) {
list, err := repositories.GetVideoCategories()
if err != nil {
utils.ServerError(c, err)
return
}
utils.Success(c, repositories.BuildVideoCategoriesResponse(list))
}
// GetVideoAlbums 获取视频专辑列表
func GetVideoAlbums(c *gin.Context) {
categoryID, _ := strconv.ParseUint(c.Query("categoryId"), 10, 32)
list, err := repositories.GetActiveVideoAlbums(uint(categoryID))
if err != nil {
utils.ServerError(c, err)
return
}
utils.Success(c, repositories.BuildVideoAlbumsResponse(list, true))
}
// GetVideoAlbumByID 获取专辑详情
func GetVideoAlbumByID(c *gin.Context) {
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
utils.Error(c, 400, "Invalid album ID")
return
}
album, err := repositories.GetVideoAlbumByID(uint(id))
if err != nil {
utils.ServerError(c, err)
return
}
if album == nil || album.IsActive != 1 {
utils.Error(c, 404, "Album not found")
return
}
utils.Success(c, repositories.BuildVideoAlbumResponse(album, true))
}
// GetAlbumVideos 获取专辑内视频
func GetAlbumVideos(c *gin.Context) {
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
utils.Error(c, 400, "Invalid album ID")
return
}
list, err := repositories.GetVideosByAlbumID(uint(id), true)
if err != nil {
utils.ServerError(c, err)
return
}
utils.Success(c, repositories.BuildVideosResponse(list))
}
// GetVideos 获取视频列表
func GetVideos(c *gin.Context) {
categoryID, _ := strconv.ParseUint(c.Query("categoryId"), 10, 32)
list, err := repositories.GetVideos(uint(categoryID), true)
if err != nil {
utils.ServerError(c, err)
return
}
utils.Success(c, repositories.BuildVideosResponse(list))
}
// GetVideoByID 获取视频详情
func GetVideoByID(c *gin.Context) {
id := c.Param("id")
video, err := repositories.GetVideoByID(id)
if err != nil {
utils.ServerError(c, err)
return
}
if video == nil || video.IsPublished != 1 {
utils.Error(c, 404, "Video not found")
return
}
utils.Success(c, repositories.BuildVideoDetailResponse(video))
}
// ========== 管理 API — 分类 ==========
func AdminGetVideoCategories(c *gin.Context) {
list, err := repositories.GetVideoCategories()
if err != nil {
utils.ServerError(c, err)
return
}
utils.Success(c, repositories.BuildVideoCategoriesResponse(list))
}
func AdminCreateVideoCategory(c *gin.Context) {
var item models.VideoCategory
if err := c.ShouldBindJSON(&item); err != nil {
utils.Error(c, 400, err.Error())
return
}
if err := repositories.CreateVideoCategory(&item); err != nil {
utils.ServerError(c, err)
return
}
utils.Success(c, repositories.BuildVideoCategoryResponse(&item))
}
func AdminUpdateVideoCategory(c *gin.Context) {
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
utils.Error(c, 400, "Invalid category ID")
return
}
var item models.VideoCategory
if err := c.ShouldBindJSON(&item); err != nil {
utils.Error(c, 400, err.Error())
return
}
item.ID = uint(id)
if err := repositories.UpdateVideoCategory(&item); err != nil {
utils.ServerError(c, err)
return
}
utils.Success(c, repositories.BuildVideoCategoryResponse(&item))
}
func AdminDeleteVideoCategory(c *gin.Context) {
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
utils.Error(c, 400, "Invalid category ID")
return
}
if err := repositories.DeleteVideoCategory(uint(id)); err != nil {
utils.ServerError(c, err)
return
}
utils.SuccessWithMsg(c, "Category deleted", nil)
}
// ========== 管理 API — 专辑 ==========
func AdminGetVideoAlbums(c *gin.Context) {
categoryID, _ := strconv.ParseUint(c.Query("categoryId"), 10, 32)
list, err := repositories.GetVideoAlbums(uint(categoryID))
if err != nil {
utils.ServerError(c, err)
return
}
utils.Success(c, repositories.BuildVideoAlbumsResponse(list, false))
}
func AdminCreateVideoAlbum(c *gin.Context) {
var item models.VideoAlbum
if err := c.ShouldBindJSON(&item); err != nil {
utils.Error(c, 400, err.Error())
return
}
if err := repositories.CreateVideoAlbum(&item); err != nil {
utils.ServerError(c, err)
return
}
utils.Success(c, repositories.BuildVideoAlbumResponse(&item, false))
}
func AdminUpdateVideoAlbum(c *gin.Context) {
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
utils.Error(c, 400, "Invalid album ID")
return
}
var req struct {
models.VideoAlbum
VideoIDs []string `json:"videoIds"`
}
if err := c.ShouldBindJSON(&req); err != nil {
utils.Error(c, 400, err.Error())
return
}
req.VideoAlbum.ID = uint(id)
if err := repositories.UpdateVideoAlbum(&req.VideoAlbum); err != nil {
utils.ServerError(c, err)
return
}
if req.VideoIDs != nil {
if err := repositories.SyncAlbumVideos(uint(id), req.VideoIDs); err != nil {
utils.ServerError(c, err)
return
}
}
utils.Success(c, repositories.BuildVideoAlbumResponse(&req.VideoAlbum, false))
}
func AdminDeleteVideoAlbum(c *gin.Context) {
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
utils.Error(c, 400, "Invalid album ID")
return
}
if err := repositories.DeleteVideoAlbum(uint(id)); err != nil {
utils.ServerError(c, err)
return
}
utils.SuccessWithMsg(c, "Album deleted", nil)
}
func AdminAddVideoToAlbum(c *gin.Context) {
albumID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
utils.Error(c, 400, "Invalid album ID")
return
}
var req struct {
VideoID string `json:"videoId"`
SortOrder uint `json:"sortOrder"`
}
if err := c.ShouldBindJSON(&req); err != nil {
utils.Error(c, 400, err.Error())
return
}
if err := repositories.AddVideoToAlbum(uint(albumID), req.VideoID, req.SortOrder); err != nil {
utils.ServerError(c, err)
return
}
utils.SuccessWithMsg(c, "Video added to album", nil)
}
func AdminRemoveVideoFromAlbum(c *gin.Context) {
albumID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
utils.Error(c, 400, "Invalid album ID")
return
}
videoID := c.Param("videoId")
if err := repositories.RemoveVideoFromAlbum(uint(albumID), videoID); err != nil {
utils.ServerError(c, err)
return
}
utils.SuccessWithMsg(c, "Video removed from album", nil)
}
func AdminGetAlbumVideoIDs(c *gin.Context) {
albumID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
utils.Error(c, 400, "Invalid album ID")
return
}
videos, err := repositories.GetVideosByAlbumID(uint(albumID), false)
if err != nil {
utils.ServerError(c, err)
return
}
ids := make([]string, 0, len(videos))
for _, v := range videos {
ids = append(ids, v.ID)
}
utils.Success(c, ids)
}
// ========== 管理 API — 视频 ==========
func AdminGetVideos(c *gin.Context) {
categoryID, _ := strconv.ParseUint(c.Query("categoryId"), 10, 32)
list, err := repositories.GetVideos(uint(categoryID), false)
if err != nil {
utils.ServerError(c, err)
return
}
utils.Success(c, repositories.BuildAdminVideosResponse(list))
}
func AdminCreateVideo(c *gin.Context) {
var req struct {
models.Video
AlbumIDs []uint `json:"albumIds"`
}
if err := c.ShouldBindJSON(&req); err != nil {
utils.Error(c, 400, err.Error())
return
}
if req.Video.ID == "" {
req.Video.ID = "video_" + strconv.FormatInt(time.Now().UnixNano(), 10)
}
if err := repositories.CreateVideo(&req.Video); err != nil {
utils.ServerError(c, err)
return
}
if req.AlbumIDs != nil {
if err := repositories.SyncVideoAlbums(req.Video.ID, req.AlbumIDs); err != nil {
utils.ServerError(c, err)
return
}
}
utils.Success(c, repositories.BuildAdminVideoResponse(&req.Video))
}
func AdminUpdateVideo(c *gin.Context) {
id := c.Param("id")
var req struct {
models.Video
AlbumIDs []uint `json:"albumIds"`
}
if err := c.ShouldBindJSON(&req); err != nil {
utils.Error(c, 400, err.Error())
return
}
req.Video.ID = id
if err := repositories.UpdateVideo(&req.Video); err != nil {
utils.ServerError(c, err)
return
}
if req.AlbumIDs != nil {
if err := repositories.SyncVideoAlbums(id, req.AlbumIDs); err != nil {
utils.ServerError(c, err)
return
}
}
video, _ := repositories.GetVideoByID(id)
if video == nil {
utils.Error(c, 404, "Video not found")
return
}
utils.Success(c, repositories.BuildAdminVideoResponse(video))
}
func AdminDeleteVideo(c *gin.Context) {
id := c.Param("id")
if err := repositories.DeleteVideo(id); err != nil {
utils.ServerError(c, err)
return
}
utils.SuccessWithMsg(c, "Video deleted", nil)
}
func AdminGetVideoByID(c *gin.Context) {
id := c.Param("id")
video, err := repositories.GetVideoByID(id)
if err != nil {
utils.ServerError(c, err)
return
}
if video == nil {
utils.Error(c, 404, "Video not found")
return
}
utils.Success(c, repositories.BuildAdminVideoResponse(video))
}