358 lines
9.3 KiB
Go
358 lines
9.3 KiB
Go
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"
|
||
"github.com/gogf/gf/v2/util/gconv"
|
||
|
||
"nl-video-api/internal/dao"
|
||
"nl-video-api/internal/model/entity"
|
||
"nl-video-api/utility/response"
|
||
)
|
||
|
||
// UserWatchHistoryService 用户观看历史服务
|
||
type UserWatchHistoryService struct{}
|
||
|
||
// NewUserWatchHistoryService 创建用户观看历史服务实例
|
||
func NewUserWatchHistoryService() *UserWatchHistoryService {
|
||
return &UserWatchHistoryService{}
|
||
}
|
||
|
||
// UserWatchHistoryCreateReq 创建观看历史请求
|
||
type UserWatchHistoryCreateReq struct {
|
||
MovieId uint `json:"movie_id" v:"required#电影ID不能为空"`
|
||
EpisodeId uint `json:"episode_id"`
|
||
Progress int `json:"progress" v:"required#观看进度不能为空"`
|
||
WatchTime int `json:"watch_time" v:"required#观看时长不能为空"`
|
||
}
|
||
|
||
// UserWatchHistoryListReq 获取观看历史列表请求
|
||
type UserWatchHistoryListReq struct {
|
||
Page int `json:"page" v:"min:1#页码最小为1"`
|
||
Size int `json:"size" v:"min:1,max:100#每页数量范围1-100"`
|
||
}
|
||
|
||
// UserWatchHistoryListRes 观看历史列表响应
|
||
type UserWatchHistoryListRes struct {
|
||
List []UserWatchHistoryItem `json:"list"`
|
||
Total int `json:"total"`
|
||
Page int `json:"page"`
|
||
Size int `json:"size"`
|
||
}
|
||
|
||
// UserWatchHistoryItem 观看历史项
|
||
type UserWatchHistoryItem struct {
|
||
Id uint `json:"id"`
|
||
MovieId uint `json:"movie_id"`
|
||
MovieTitle string `json:"movie_title"`
|
||
MoviePoster string `json:"movie_poster"`
|
||
EpisodeId uint `json:"episode_id"`
|
||
EpisodeTitle string `json:"episode_title"`
|
||
Progress int `json:"progress"`
|
||
WatchTime int `json:"watch_time"`
|
||
LastWatchTime int64 `json:"last_watch_time"`
|
||
CreatedAt int64 `json:"created_at"`
|
||
}
|
||
|
||
// UserWatchHistoryClearReq 清空观看历史请求
|
||
type UserWatchHistoryClearReq struct {
|
||
UserId uint `json:"user_id"`
|
||
}
|
||
|
||
// UserWatchHistoryProgressReq 获取观看进度请求
|
||
type UserWatchHistoryProgressReq struct {
|
||
MovieId uint `json:"movie_id" v:"required#电影ID不能为空"`
|
||
EpisodeId uint `json:"episode_id"`
|
||
}
|
||
|
||
// UserWatchHistoryProgressRes 观看进度响应
|
||
type UserWatchHistoryProgressRes struct {
|
||
Progress int `json:"progress"`
|
||
WatchTime int `json:"watch_time"`
|
||
LastWatchTime int64 `json:"last_watch_time"`
|
||
}
|
||
|
||
// Create 创建观看历史
|
||
func (s *UserWatchHistoryService) Create(r *ghttp.Request) {
|
||
var req UserWatchHistoryCreateReq
|
||
if err := r.Parse(&req); err != nil {
|
||
response.Error(r, response.CodeInvalidParam, err.Error())
|
||
return
|
||
}
|
||
|
||
// 获取用户ID(从JWT token或session中获取)
|
||
userId := GetUserIdFromContext(r.Context())
|
||
|
||
// 检查是否已存在观看历史
|
||
var existHistory entity.UserWatchHistory
|
||
err := dao.UserWatchHistory.Ctx(r.Context()).
|
||
Where("user_id", userId).
|
||
Where("movie_id", req.MovieId).
|
||
Where("episode_id", req.EpisodeId).
|
||
Scan(&existHistory)
|
||
|
||
if err != nil && !g.IsEmpty(existHistory) {
|
||
response.Error(r, response.CodeInternalError, "系统错误")
|
||
return
|
||
}
|
||
|
||
if existHistory.Id > 0 {
|
||
// 更新现有记录
|
||
_, err = dao.UserWatchHistory.Ctx(r.Context()).
|
||
Where("id", existHistory.Id).
|
||
Update(g.Map{
|
||
"progress": req.Progress,
|
||
"watch_time": req.WatchTime,
|
||
"last_watch_time": gtime.Now(),
|
||
"updated_at": gtime.Now(),
|
||
})
|
||
} else {
|
||
// 创建新记录
|
||
history := &entity.UserWatchHistory{
|
||
UserId: gconv.Int(userId),
|
||
MovieId: gconv.Int(req.MovieId),
|
||
EpisodeId: gconv.Int(req.EpisodeId),
|
||
Progress: float64(req.Progress),
|
||
WatchTime: req.WatchTime,
|
||
LastWatchTime: int(gtime.Now().Unix()),
|
||
CreatedAt: gtime.Now(),
|
||
}
|
||
|
||
_, err = dao.UserWatchHistory.Ctx(r.Context()).Insert(history)
|
||
}
|
||
|
||
if err != nil {
|
||
response.Error(r, response.CodeInternalError, "保存观看历史失败")
|
||
return
|
||
}
|
||
|
||
response.Success(r, "保存成功")
|
||
}
|
||
|
||
// GetList 获取观看历史列表
|
||
func (s *UserWatchHistoryService) GetList(r *ghttp.Request) {
|
||
var req UserWatchHistoryListReq
|
||
if err := r.Parse(&req); err != nil {
|
||
response.Error(r, response.CodeInvalidParam, err.Error())
|
||
return
|
||
}
|
||
|
||
// 设置默认值
|
||
if req.Page <= 0 {
|
||
req.Page = 1
|
||
}
|
||
if req.Size <= 0 {
|
||
req.Size = 10
|
||
}
|
||
|
||
// 获取用户ID
|
||
userId := GetUserIdFromContext(r.Context())
|
||
|
||
// 构建查询
|
||
query := dao.UserWatchHistory.Ctx(r.Context()).Where("user_id", userId)
|
||
|
||
// 获取总数
|
||
total, err := query.Count()
|
||
if err != nil {
|
||
response.Error(r, response.CodeInternalError, "获取数据失败")
|
||
return
|
||
}
|
||
|
||
// 获取列表数据
|
||
var histories []entity.UserWatchHistory
|
||
err = query.Order("last_watch_time DESC").
|
||
Limit((req.Page-1)*req.Size, req.Size).
|
||
Scan(&histories)
|
||
|
||
if err != nil {
|
||
response.Error(r, response.CodeInternalError, "获取数据失败")
|
||
return
|
||
}
|
||
|
||
// 构建响应数据
|
||
var list []UserWatchHistoryItem
|
||
for _, history := range histories {
|
||
// 获取电影信息
|
||
var movie entity.Movie
|
||
err = g.DB().Model("movie").Where("id", history.MovieId).Scan(&movie)
|
||
if err != nil {
|
||
continue
|
||
}
|
||
|
||
// 获取剧集信息(如果有)
|
||
var episode entity.Episode
|
||
episodeTitle := ""
|
||
if history.EpisodeId > 0 {
|
||
err = g.DB().Model("episode").Where("id", history.EpisodeId).Scan(&episode)
|
||
if err == nil {
|
||
episodeTitle = episode.Title
|
||
}
|
||
}
|
||
|
||
list = append(list, UserWatchHistoryItem{
|
||
Id: gconv.Uint(history.Id),
|
||
MovieId: gconv.Uint(history.MovieId),
|
||
MovieTitle: movie.Title,
|
||
MoviePoster: movie.Poster,
|
||
EpisodeId: gconv.Uint(history.EpisodeId),
|
||
EpisodeTitle: episodeTitle,
|
||
Progress: int(history.Progress),
|
||
WatchTime: history.WatchTime,
|
||
LastWatchTime: int64(history.LastWatchTime),
|
||
CreatedAt: history.CreatedAt.Unix(),
|
||
})
|
||
}
|
||
|
||
res := UserWatchHistoryListRes{
|
||
List: list,
|
||
Total: total,
|
||
Page: req.Page,
|
||
Size: req.Size,
|
||
}
|
||
|
||
response.Success(r, res)
|
||
}
|
||
|
||
// Delete 删除观看历史
|
||
func (s *UserWatchHistoryService) Delete(r *ghttp.Request) {
|
||
id := r.Get("id").Uint()
|
||
if id == 0 {
|
||
response.Error(r, response.CodeInvalidParam, "ID不能为空")
|
||
return
|
||
}
|
||
|
||
// 获取用户ID
|
||
userId := GetUserIdFromContext(r.Context())
|
||
|
||
// 删除记录
|
||
_, err := dao.UserWatchHistory.Ctx(r.Context()).
|
||
Where("id", id).
|
||
Where("user_id", userId).
|
||
Delete()
|
||
|
||
if err != nil {
|
||
response.Error(r, response.CodeInternalError, "删除失败")
|
||
return
|
||
}
|
||
|
||
response.Success(r, "删除成功")
|
||
}
|
||
|
||
// Clear 清空观看历史
|
||
func (s *UserWatchHistoryService) Clear(ctx context.Context, req *UserWatchHistoryClearReq) error {
|
||
// 删除用户的所有观看历史
|
||
_, err := dao.UserWatchHistory.Ctx(ctx).
|
||
Where("user_id", req.UserId).
|
||
Delete()
|
||
|
||
if err != nil {
|
||
return gerror.New("清空观看历史失败")
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// Add 添加观看历史
|
||
func (s *UserWatchHistoryService) Add(r *ghttp.Request) {
|
||
var req UserWatchHistoryCreateReq
|
||
if err := r.Parse(&req); err != nil {
|
||
response.Error(r, response.CodeInvalidParam, err.Error())
|
||
return
|
||
}
|
||
|
||
// 获取用户ID
|
||
userId := GetUserIdFromContext(r.Context())
|
||
|
||
// 检查是否已存在观看历史
|
||
var existHistory entity.UserWatchHistory
|
||
err := dao.UserWatchHistory.Ctx(r.Context()).
|
||
Where("user_id", userId).
|
||
Where("movie_id", req.MovieId).
|
||
Where("episode_id", req.EpisodeId).
|
||
Scan(&existHistory)
|
||
|
||
if err != nil && !g.IsEmpty(existHistory) {
|
||
response.Error(r, response.CodeInternalError, "系统错误")
|
||
return
|
||
}
|
||
|
||
if existHistory.Id > 0 {
|
||
// 更新现有记录
|
||
_, err = dao.UserWatchHistory.Ctx(r.Context()).
|
||
Where("id", existHistory.Id).
|
||
Update(g.Map{
|
||
"progress": req.Progress,
|
||
"watch_time": req.WatchTime,
|
||
"last_watch_time": gtime.Now().Unix(),
|
||
"updated_at": gtime.Now(),
|
||
})
|
||
} else {
|
||
// 创建新记录
|
||
history := &entity.UserWatchHistory{
|
||
UserId: gconv.Int(userId),
|
||
MovieId: gconv.Int(req.MovieId),
|
||
EpisodeId: gconv.Int(req.EpisodeId),
|
||
Progress: float64(req.Progress),
|
||
WatchTime: req.WatchTime,
|
||
LastWatchTime: int(gtime.Now().Unix()),
|
||
CreatedAt: gtime.Now(),
|
||
}
|
||
|
||
_, err = dao.UserWatchHistory.Ctx(r.Context()).Insert(history)
|
||
}
|
||
|
||
if err != nil {
|
||
response.Error(r, response.CodeInternalError, "保存观看历史失败")
|
||
return
|
||
}
|
||
|
||
response.Success(r, "保存成功")
|
||
}
|
||
|
||
// GetProgress 获取观看进度
|
||
func (s *UserWatchHistoryService) GetProgress(r *ghttp.Request) {
|
||
var req UserWatchHistoryProgressReq
|
||
if err := r.Parse(&req); err != nil {
|
||
response.Error(r, response.CodeInvalidParam, err.Error())
|
||
return
|
||
}
|
||
|
||
// 获取用户ID
|
||
userId := GetUserIdFromContext(r.Context())
|
||
|
||
// 查询观看历史
|
||
var history entity.UserWatchHistory
|
||
err := dao.UserWatchHistory.Ctx(r.Context()).
|
||
Where("user_id", userId).
|
||
Where("movie_id", req.MovieId).
|
||
Where("episode_id", req.EpisodeId).
|
||
Scan(&history)
|
||
|
||
if err != nil && !g.IsEmpty(history) {
|
||
response.Error(r, response.CodeInternalError, "获取观看进度失败")
|
||
return
|
||
}
|
||
|
||
var res UserWatchHistoryProgressRes
|
||
if history.Id > 0 {
|
||
res = UserWatchHistoryProgressRes{
|
||
Progress: int(history.Progress),
|
||
WatchTime: history.WatchTime,
|
||
LastWatchTime: int64(history.LastWatchTime),
|
||
}
|
||
} else {
|
||
res = UserWatchHistoryProgressRes{
|
||
Progress: 0,
|
||
WatchTime: 0,
|
||
LastWatchTime: 0,
|
||
}
|
||
}
|
||
|
||
response.Success(r, res)
|
||
}
|
||
|