429 lines
11 KiB
Go
429 lines
11 KiB
Go
|
|
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, "批量删除成功")
|
|||
|
|
}
|