package service import ( "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/utility/response" ) // CommentService 评论服务 type CommentService struct{} // NewCommentService 创建评论服务实例 func NewCommentService() *CommentService { return &CommentService{} } // Add 添加评论 func (s *CommentService) Add(r *ghttp.Request) { // 获取用户ID(这里应该从JWT token中获取) userId := r.Get("user_id").Uint() if userId == 0 { response.Error(r, response.CodeUnauthorized, "用户未登录") return } // 获取请求参数 movieId := r.Get("movie_id").Uint() if movieId == 0 { response.Error(r, response.CodeInvalidParam, "电影ID不能为空") return } content := r.Get("content").String() if content == "" { response.Error(r, response.CodeInvalidParam, "评论内容不能为空") return } parentId := r.Get("parent_id").Uint() // 检查电影是否存在 movieCount, err := g.DB().Model("movie").Where("id", movieId).Count() if err != nil { response.Error(r, response.CodeInternalError, "系统错误") return } if movieCount == 0 { response.Error(r, response.CodeNotFound, "电影不存在") return } // 如果是回复评论,检查父评论是否存在 if parentId > 0 { parentCount, err := dao.Comment.Ctx(r.Context()).Where("id", parentId).Where("movie_id", movieId).Count() if err != nil { response.Error(r, response.CodeInternalError, "系统错误") return } if parentCount == 0 { response.Error(r, response.CodeNotFound, "父评论不存在") return } } // 创建评论 commentId, err := dao.Comment.Ctx(r.Context()).Data(g.Map{ "user_id": userId, "movie_id": movieId, "parent_id": parentId, "content": content, "like_count": 0, "status": 1, // 默认通过审核 "created_at": gtime.Now(), "updated_at": gtime.Now(), }).InsertAndGetId() if err != nil { response.Error(r, response.CodeInternalError, "添加评论失败") return } response.Success(r, g.Map{ "id": commentId, }) } // GetList 获取评论列表 func (s *CommentService) GetList(r *ghttp.Request) { movieId := r.Get("movie_id").Uint() if movieId == 0 { response.Error(r, response.CodeInvalidParam, "电影ID不能为空") return } page := r.Get("page", 1).Int() size := r.Get("size", 10).Int() parentId := r.Get("parent_id", 0).Uint() // 构建查询条件 query := dao.Comment.Ctx(r.Context()).Where("movie_id", movieId).Where("status", 1) if parentId > 0 { query = query.Where("parent_id", parentId) } else { query = query.Where("parent_id", 0) } // 获取总数 total, err := query.Count() if err != nil { response.Error(r, response.CodeInternalError, "获取评论总数失败") return } // 获取评论列表 var comments []g.Map err = query.Order("created_at DESC"). Limit((page-1)*size, size). Scan(&comments) if err != nil { response.Error(r, response.CodeInternalError, "获取评论列表失败") return } // 获取用户信息 userIds := make([]interface{}, 0) for _, comment := range comments { userIds = append(userIds, comment["user_id"]) } userMap := make(map[uint]g.Map) if len(userIds) > 0 { var users []g.Map g.DB().Model("nl_user").WhereIn("id", userIds).Fields("id, username, avatar").Scan(&users) for _, user := range users { userMap[gconv.Uint(user["id"])] = user } } // 组装返回数据 list := make([]g.Map, 0) for _, comment := range comments { userId := gconv.Uint(comment["user_id"]) user := userMap[userId] item := g.Map{ "id": comment["id"], "user_id": comment["user_id"], "username": user["username"], "avatar": user["avatar"], "movie_id": comment["movie_id"], "parent_id": comment["parent_id"], "content": comment["content"], "like_count": comment["like_count"], "created_at": gconv.Int64(comment["created_at"]), "replies": make([]g.Map, 0), // 子评论,如果需要可以递归获取 } list = append(list, item) } response.Success(r, g.Map{ "list": list, "total": total, "page": page, "size": size, }) } // Delete 删除评论 func (s *CommentService) Delete(r *ghttp.Request) { // 获取用户ID userId := r.Get("user_id").Uint() if userId == 0 { response.Error(r, response.CodeUnauthorized, "用户未登录") return } commentId := r.Get("id").Uint() if commentId == 0 { response.Error(r, response.CodeInvalidParam, "评论ID不能为空") return } // 检查评论是否存在且属于当前用户 var comment g.Map err := dao.Comment.Ctx(r.Context()).Where("id", commentId).Where("user_id", userId).Scan(&comment) if err != nil { response.Error(r, response.CodeInternalError, "系统错误") return } if len(comment) == 0 { response.Error(r, response.CodeNotFound, "评论不存在或无权限删除") return } // 删除评论(软删除,更新状态) _, err = dao.Comment.Ctx(r.Context()).Where("id", commentId).Data(g.Map{ "status": 0, // 0表示已删除 "updated_at": gtime.Now(), }).Update() if err != nil { response.Error(r, response.CodeInternalError, "删除评论失败") return } // 同时删除该评论的所有回复 _, err = dao.Comment.Ctx(r.Context()).Where("parent_id", commentId).Data(g.Map{ "status": 0, "updated_at": gtime.Now(), }).Update() if err != nil { // 记录日志,但不影响主要操作 g.Log().Error(r.Context(), "删除子评论失败:", err) } response.Success(r, "删除成功") } // Like 点赞评论 func (s *CommentService) Like(r *ghttp.Request) { // 获取用户ID userId := r.Get("user_id").Uint() if userId == 0 { response.Error(r, response.CodeUnauthorized, "用户未登录") return } commentId := r.Get("id").Uint() if commentId == 0 { response.Error(r, response.CodeInvalidParam, "评论ID不能为空") return } // 检查评论是否存在 commentCount, err := dao.Comment.Ctx(r.Context()).Where("id", commentId).Where("status", 1).Count() if err != nil { response.Error(r, response.CodeInternalError, "系统错误") return } if commentCount == 0 { response.Error(r, response.CodeNotFound, "评论不存在") return } // 检查是否已经点赞 likeCount, err := g.DB().Model("comment_like").Where("user_id", userId).Where("comment_id", commentId).Count() if err != nil { response.Error(r, response.CodeInternalError, "系统错误") return } if likeCount > 0 { // 取消点赞 _, err = g.DB().Model("comment_like").Where("user_id", userId).Where("comment_id", commentId).Delete() if err != nil { response.Error(r, response.CodeInternalError, "取消点赞失败") return } // 减少点赞数 _, err = dao.Comment.Ctx(r.Context()).Where("id", commentId).Data("like_count=like_count-1").Update() if err != nil { response.Error(r, response.CodeInternalError, "更新点赞数失败") return } response.Success(r, g.Map{ "action": "unlike", "message": "取消点赞成功", }) } else { // 添加点赞 _, err = g.DB().Model("comment_like").Data(g.Map{ "user_id": userId, "comment_id": commentId, "created_at": gtime.Now(), }).Insert() if err != nil { response.Error(r, response.CodeInternalError, "点赞失败") return } // 增加点赞数 _, err = dao.Comment.Ctx(r.Context()).Where("id", commentId).Data("like_count=like_count+1").Update() if err != nil { response.Error(r, response.CodeInternalError, "更新点赞数失败") return } response.Success(r, g.Map{ "action": "like", "message": "点赞成功", }) } } // Report 举报评论 func (s *CommentService) Report(r *ghttp.Request) { // 获取请求参数 id := r.Get("id").Uint() reason := r.Get("reason").String() // 参数验证 if id == 0 { response.Error(r, response.CodeInvalidParam, "评论ID不能为空") return } if reason == "" { response.Error(r, response.CodeInvalidParam, "举报原因不能为空") return } // 检查评论是否存在 count, err := dao.Comment.Ctx(r.Context()).Where("id", id).Count() if err != nil { response.Error(r, response.CodeInternalError, "检查评论失败") return } if count == 0 { response.Error(r, response.CodeNotFound, "评论不存在") return } // 这里应该实现举报逻辑,创建举报记录 response.Success(r, "举报成功") } // Unlike 取消点赞评论 func (s *CommentService) Unlike(r *ghttp.Request) { // 获取请求参数 id := r.Get("id").Uint() // 参数验证 if id == 0 { response.Error(r, response.CodeInvalidParam, "评论ID不能为空") return } // 检查评论是否存在 count, err := dao.Comment.Ctx(r.Context()).Where("id", id).Count() if err != nil { response.Error(r, response.CodeInternalError, "检查评论失败") return } if count == 0 { response.Error(r, response.CodeNotFound, "评论不存在") return } // 这里应该实现取消点赞逻辑 response.Success(r, "取消点赞成功") } // AdminList 管理员获取评论列表 func (s *CommentService) AdminList(r *ghttp.Request) { s.AdminGetList(r) } // AdminUpdateStatus 管理员更新评论状态 func (s *CommentService) AdminUpdateStatus(r *ghttp.Request) { // 获取请求参数 id := r.Get("id").Uint() status := r.Get("status").Int() // 参数验证 if id == 0 { response.Error(r, response.CodeInvalidParam, "评论ID不能为空") return } // 检查评论是否存在 count, err := dao.Comment.Ctx(r.Context()).Where("id", id).Count() if err != nil { response.Error(r, response.CodeInternalError, "检查评论失败") return } if count == 0 { response.Error(r, response.CodeNotFound, "评论不存在") return } // 更新评论状态 _, err = dao.Comment.Ctx(r.Context()).Where("id", id).Data(g.Map{ "status": status, "updated_at": gtime.Now(), }).Update() if err != nil { response.Error(r, response.CodeInternalError, "更新评论状态失败") return } response.Success(r, "更新成功") } // AdminGetList 管理员获取评论列表 func (s *CommentService) AdminGetList(r *ghttp.Request) { s.GetList(r) } // AdminBatchDelete 管理员批量删除评论 func (s *CommentService) AdminBatchDelete(r *ghttp.Request) { // 获取请求参数 var ids []uint r.Parse(&ids) if len(ids) == 0 { response.Error(r, response.CodeInvalidParam, "请选择要删除的评论") return } // 批量删除评论(软删除) _, err := dao.Comment.Ctx(r.Context()).WhereIn("id", ids).Data(g.Map{ "status": 0, "updated_at": gtime.Now(), }).Update() if err != nil { response.Error(r, response.CodeInternalError, "批量删除评论失败") return } response.Success(r, "批量删除成功") }