package service import ( "context" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/os/gtime" "nl-video-api/internal/dao" "nl-video-api/internal/model/entity" "nl-video-api/utility/response" ) // UserCollectService 用户收藏服务 type UserCollectService struct{} // NewUserCollectService 创建用户收藏服务实例 func NewUserCollectService() *UserCollectService { return &UserCollectService{} } // GetList 获取用户收藏列表 func (s *UserCollectService) GetList(r *ghttp.Request) { // 获取请求参数 page := r.Get("page", 1).Int() size := r.Get("size", 10).Int() // 获取当前用户ID(临时设置) userId := uint(1) // 构建查询条件 query := dao.UserCollect.Ctx(r.Context()).Where("user_id", userId) // 获取总数 total, err := query.Count() if err != nil { response.Error(r, response.CodeInternalError, "获取收藏总数失败") return } // 获取列表数据 var collects []entity.UserCollect err = query.Order("created_at DESC"). Limit((page-1)*size, size). Scan(&collects) if err != nil { response.Error(r, response.CodeInternalError, "获取收藏列表失败") return } response.Success(r, g.Map{ "list": collects, "total": total, "page": page, "size": size, }) } // CheckCollect 检查是否已收藏 func (s *UserCollectService) CheckCollect(r *ghttp.Request) { // 获取请求参数 movieId := r.Get("movie_id").Uint() // 参数验证 if movieId == 0 { response.Error(r, response.CodeInvalidParam, "电影ID不能为空") return } // 获取当前用户ID(临时设置) userId := uint(1) // 检查是否已收藏 count, err := dao.UserCollect.Ctx(r.Context()). Where("user_id", userId). Where("movie_id", movieId). Count() if err != nil { response.Error(r, response.CodeInternalError, "检查收藏状态失败") return } response.Success(r, g.Map{ "is_collected": count > 0, }) } // 定义请求和响应结构体 type UserCollectAddReq struct { MovieId uint `json:"movie_id"` } type UserCollectRemoveReq struct { MovieId uint `json:"movie_id"` } type UserCollectListReq struct { Page int `json:"page"` Size int `json:"size"` } type UserCollectListRes struct { List []UserCollectItem `json:"list"` Total int `json:"total"` Page int `json:"page"` Size int `json:"size"` } type UserCollectItem struct { Id uint `json:"id"` MovieId uint `json:"movie_id"` MovieName string `json:"movie_name"` MovieCover string `json:"movie_cover"` CreatedAt int64 `json:"created_at"` } type UserCollectCheckReq struct { MovieId uint `json:"movie_id"` } type UserCollectCheckRes struct { IsCollected bool `json:"is_collected"` } // Add 添加收藏 func (s *UserCollectService) Add(r *ghttp.Request) { // 获取请求参数 movieId := r.Get("movie_id").Uint() if movieId == 0 { response.Error(r, response.CodeInvalidParam, "电影ID不能为空") return } // 获取当前用户ID userId := uint(1) // 临时设置,实际应该从JWT中获取 if userId == 0 { response.Error(r, response.CodeUnauthorized, "用户未登录") return } // 检查电影是否存在 var movie entity.Movie err := g.DB().Model("movie").Where("id", movieId).Scan(&movie) if err != nil { response.Error(r, response.CodeInternalError, "系统错误") return } if movie.Id == 0 { response.Error(r, response.CodeNotFound, "电影不存在") return } // 检查是否已经收藏 count, err := dao.UserCollect.Ctx(r.Context()).Where("user_id", userId).Where("movie_id", movieId).Count() if err != nil { response.Error(r, response.CodeInternalError, "系统错误") return } if count > 0 { response.Error(r, response.CodeInvalidParam, "已经收藏过该电影") return } // 添加收藏 data := &entity.UserCollect{ UserId: int(userId), MovieId: int(movieId), Type: 1, // 影片收藏 TargetId: int(movieId), CreatedAt: gtime.Now(), } id, err := dao.UserCollect.Ctx(r.Context()).Data(data).InsertAndGetId() if err != nil { response.Error(r, response.CodeInternalError, "添加收藏失败") return } response.Success(r, g.Map{ "id": uint(id), }) } // Remove 取消收藏 func (s *UserCollectService) Remove(r *ghttp.Request) { // 获取请求参数 movieId := r.Get("movie_id").Uint() if movieId == 0 { response.Error(r, response.CodeInvalidParam, "电影ID不能为空") return } // 获取当前用户ID userId := uint(1) // 临时设置,实际应该从JWT中获取 if userId == 0 { response.Error(r, response.CodeUnauthorized, "用户未登录") return } // 检查收藏是否存在 count, err := dao.UserCollect.Ctx(r.Context()).Where("user_id", userId).Where("movie_id", movieId).Count() if err != nil { response.Error(r, response.CodeInternalError, "系统错误") return } if count == 0 { response.Error(r, response.CodeNotFound, "收藏不存在") return } // 删除收藏 _, err = dao.UserCollect.Ctx(r.Context()).Where("user_id", userId).Where("movie_id", movieId).Delete() if err != nil { response.Error(r, response.CodeInternalError, "取消收藏失败") return } response.Success(r, "取消收藏成功") } // List 获取收藏列表 func (s *UserCollectService) List(ctx context.Context, req *UserCollectListReq) (*UserCollectListRes, error) { // 设置默认值 if req.Page <= 0 { req.Page = 1 } if req.Size <= 0 { req.Size = 10 } // 获取当前用户ID userId := uint(1) // 临时设置,实际应该从JWT中获取 if userId == 0 { return nil, gerror.New("用户未登录") } // 构建查询条件 query := dao.UserCollect.Ctx(ctx).Where("user_id", userId) // 获取总数 total, err := query.Count() if err != nil { return nil, gerror.New("获取收藏总数失败") } // 获取列表数据 var collects []entity.UserCollect err = query.Order("id DESC"). Limit((req.Page-1)*req.Size, req.Size). Scan(&collects) if err != nil { return nil, gerror.New("获取收藏列表失败") } // 获取电影信息 movieIds := make([]int, 0, len(collects)) for _, collect := range collects { movieIds = append(movieIds, collect.MovieId) } movieMap := make(map[int]entity.Movie) if len(movieIds) > 0 { var movies []entity.Movie g.DB().Model("movie").WhereIn("id", movieIds).Fields("id, name, cover").Scan(&movies) for _, movie := range movies { movieMap[int(movie.Id)] = movie } } // 转换为响应格式 list := make([]UserCollectItem, 0, len(collects)) for _, collect := range collects { movie := movieMap[collect.MovieId] list = append(list, UserCollectItem{ Id: collect.Id, MovieId: uint(collect.MovieId), MovieName: movie.Title, MovieCover: movie.Poster, CreatedAt: collect.CreatedAt.Unix(), }) } return &UserCollectListRes{ List: list, Total: total, Page: req.Page, Size: req.Size, }, nil } // Check 检查是否收藏 func (s *UserCollectService) Check(ctx context.Context, req *UserCollectCheckReq) (*UserCollectCheckRes, error) { // 获取当前用户ID userId := uint(1) // 临时设置,实际应该从JWT中获取 if userId == 0 { return nil, gerror.New("用户未登录") } // 检查是否收藏 count, err := dao.UserCollect.Ctx(ctx).Where("user_id", userId).Where("movie_id", req.MovieId).Count() if err != nil { return nil, gerror.New("检查收藏状态失败") } return &UserCollectCheckRes{ IsCollected: count > 0, }, nil } // GetUserCollectCount 获取用户收藏数量 func (s *UserCollectService) GetUserCollectCount(ctx context.Context, userId uint) (int, error) { count, err := dao.UserCollect.Ctx(ctx).Where("user_id", userId).Count() if err != nil { return 0, gerror.New("获取用户收藏数量失败") } return count, nil } // GetMovieCollectCount 获取电影收藏数量 func (s *UserCollectService) GetMovieCollectCount(ctx context.Context, movieId uint) (int, error) { count, err := dao.UserCollect.Ctx(ctx).Where("movie_id", movieId).Count() if err != nil { return 0, gerror.New("获取电影收藏数量失败") } return count, nil } // BatchRemove 批量取消收藏 func (s *UserCollectService) BatchRemove(ctx context.Context, userId uint, movieIds []uint) error { if len(movieIds) == 0 { return gerror.New("请选择要取消收藏的电影") } _, err := dao.UserCollect.Ctx(ctx).Where("user_id", userId).WhereIn("movie_id", movieIds).Delete() if err != nil { return gerror.New("批量取消收藏失败") } return nil } // GetPopularMovies 获取热门收藏电影 func (s *UserCollectService) GetPopularMovies(ctx context.Context, limit int) ([]g.Map, error) { if limit <= 0 { limit = 10 } var result []g.Map err := dao.UserCollect.Ctx(ctx). Fields("movie_id, COUNT(*) as collect_count"). Group("movie_id"). Order("collect_count DESC"). Limit(limit). Scan(&result) if err != nil { return nil, gerror.New("获取热门收藏电影失败") } return result, nil } // GetRecentCollects 获取最近收藏 func (s *UserCollectService) GetRecentCollects(ctx context.Context, userId uint, limit int) ([]UserCollectItem, error) { if limit <= 0 { limit = 10 } // 获取最近收藏 var collects []entity.UserCollect err := dao.UserCollect.Ctx(ctx). Where("user_id", userId). Order("created_at DESC"). Limit(limit). Scan(&collects) if err != nil { return nil, gerror.New("获取最近收藏失败") } // 获取电影信息 movieIds := make([]int, 0, len(collects)) for _, collect := range collects { movieIds = append(movieIds, collect.MovieId) } movieMap := make(map[int]entity.Movie) if len(movieIds) > 0 { var movies []entity.Movie g.DB().Model("movie").WhereIn("id", movieIds).Fields("id, name, cover").Scan(&movies) for _, movie := range movies { movieMap[int(movie.Id)] = movie } } // 转换为响应格式 list := make([]UserCollectItem, 0, len(collects)) for _, collect := range collects { movie := movieMap[collect.MovieId] list = append(list, UserCollectItem{ Id: collect.Id, MovieId: uint(collect.MovieId), MovieName: movie.Title, MovieCover: movie.Poster, CreatedAt: collect.CreatedAt.Unix(), }) } return list, nil }