feat: 添加了评论功能并注册
This commit is contained in:
@@ -23,7 +23,7 @@ func NewDB(dbcfg config.DatabaseConfig) (*gorm.DB, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func AutoMigrate(db *gorm.DB) error {
|
func AutoMigrate(db *gorm.DB) error {
|
||||||
return db.AutoMigrate(&account.Account{}, &video.Video{}, &video.Like{})
|
return db.AutoMigrate(&account.Account{}, &video.Video{}, &video.Like{}, &video.Comment{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func CloseDB(db *gorm.DB) error {
|
func CloseDB(db *gorm.DB) error {
|
||||||
|
|||||||
@@ -59,12 +59,26 @@ func SetRouter(db *gorm.DB) *gin.Engine {
|
|||||||
protectedLikeGroup.POST("/unlike", likeHandler.Unlike)
|
protectedLikeGroup.POST("/unlike", likeHandler.Unlike)
|
||||||
protectedLikeGroup.POST("/isLiked", likeHandler.IsLiked)
|
protectedLikeGroup.POST("/isLiked", likeHandler.IsLiked)
|
||||||
}
|
}
|
||||||
|
// comment
|
||||||
|
commentRepository := video.NewCommentRepository(db)
|
||||||
|
commentService := video.NewCommentService(commentRepository, videoRepository)
|
||||||
|
commentHandler := video.NewCommentHandler(commentService, accountService)
|
||||||
|
commentGroup := r.Group("/comment")
|
||||||
|
{
|
||||||
|
commentGroup.POST("/listAll", commentHandler.GetAllComments)
|
||||||
|
}
|
||||||
|
protectedCommentGroup := commentGroup.Group("")
|
||||||
|
protectedCommentGroup.Use(middleware.JWTAuth(accountRepository))
|
||||||
|
{
|
||||||
|
protectedCommentGroup.POST("/publish", commentHandler.PublishComment)
|
||||||
|
protectedCommentGroup.POST("/delete", commentHandler.DeleteComment)
|
||||||
|
}
|
||||||
// feed
|
// feed
|
||||||
feedRepository := feed.NewFeedRepository(db)
|
feedRepository := feed.NewFeedRepository(db)
|
||||||
feedService := feed.NewFeedService(feedRepository, likeRepository)
|
feedService := feed.NewFeedService(feedRepository, likeRepository)
|
||||||
feedHandler := feed.NewFeedHandler(feedService)
|
feedHandler := feed.NewFeedHandler(feedService)
|
||||||
feedGroup := r.Group("/feed")
|
feedGroup := r.Group("/feed")
|
||||||
|
feedGroup.Use(middleware.SoftJWTAuth(accountRepository))
|
||||||
{
|
{
|
||||||
feedGroup.POST("/listLatest", feedHandler.ListLatest)
|
feedGroup.POST("/listLatest", feedHandler.ListLatest)
|
||||||
feedGroup.POST("/listLikesCount", feedHandler.ListLikesCount)
|
feedGroup.POST("/listLikesCount", feedHandler.ListLikesCount)
|
||||||
|
|||||||
25
internal/video/comment_entity.go
Normal file
25
internal/video/comment_entity.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package video
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Comment struct {
|
||||||
|
ID uint `gorm:"primaryKey" json:"id"`
|
||||||
|
Username string `gorm:"index" json:"username"`
|
||||||
|
VideoID uint `gorm:"index" json:"video_id"`
|
||||||
|
AuthorID uint `gorm:"index" json:"author_id"`
|
||||||
|
Content string `gorm:"type:text" json:"content"`
|
||||||
|
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PublishCommentRequest struct {
|
||||||
|
VideoID uint `json:"video_id"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteCommentRequest struct {
|
||||||
|
CommentID uint `json:"comment_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetAllCommentsRequest struct {
|
||||||
|
VideoID uint `json:"video_id"`
|
||||||
|
}
|
||||||
93
internal/video/comment_handler.go
Normal file
93
internal/video/comment_handler.go
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
package video
|
||||||
|
|
||||||
|
import (
|
||||||
|
"feedsystem_video_go/internal/account"
|
||||||
|
"feedsystem_video_go/internal/middleware"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CommentHandler struct {
|
||||||
|
service *CommentService
|
||||||
|
accountService *account.AccountService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCommentHandler(service *CommentService, accountService *account.AccountService) *CommentHandler {
|
||||||
|
return &CommentHandler{service: service, accountService: accountService}
|
||||||
|
}
|
||||||
|
func (h *CommentHandler) PublishComment(c *gin.Context) {
|
||||||
|
var req PublishCommentRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if req.Content == "" {
|
||||||
|
c.JSON(400, gin.H{"error": "content is required"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if req.VideoID <= 0 {
|
||||||
|
c.JSON(400, gin.H{"error": "video_id is required"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
authorId, err := middleware.GetAccountID(c)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user, err := h.accountService.FindByID(c.Request.Context(), authorId)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
comment := &Comment{
|
||||||
|
Username: user.Username,
|
||||||
|
VideoID: req.VideoID,
|
||||||
|
AuthorID: authorId,
|
||||||
|
Content: req.Content,
|
||||||
|
}
|
||||||
|
if err := h.service.Publish(c.Request.Context(), comment); err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(200, gin.H{"message": "comment published successfully"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *CommentHandler) DeleteComment(c *gin.Context) {
|
||||||
|
var req DeleteCommentRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
accountID, err := middleware.GetAccountID(c)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if req.CommentID <= 0 {
|
||||||
|
c.JSON(400, gin.H{"error": "comment_id is required"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := h.service.Delete(c.Request.Context(), req.CommentID, accountID); err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(200, gin.H{"message": "comment deleted successfully"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *CommentHandler) GetAllComments(c *gin.Context) {
|
||||||
|
var req GetAllCommentsRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if req.VideoID == 0 {
|
||||||
|
c.JSON(400, gin.H{"error": "video_id is required"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
comments, err := h.service.GetAll(c.Request.Context(), req.VideoID)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(400, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(200, comments)
|
||||||
|
}
|
||||||
51
internal/video/comment_repo.go
Normal file
51
internal/video/comment_repo.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package video
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CommentRepository struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCommentRepository(db *gorm.DB) *CommentRepository {
|
||||||
|
return &CommentRepository{db: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CommentRepository) CreateComment(ctx context.Context, comment *Comment) error {
|
||||||
|
return r.db.WithContext(ctx).Create(comment).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CommentRepository) DeleteComment(ctx context.Context, comment *Comment) error {
|
||||||
|
return r.db.WithContext(ctx).Delete(comment).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CommentRepository) GetAllComments(ctx context.Context, videoID uint) ([]Comment, error) {
|
||||||
|
var comments []Comment
|
||||||
|
err := r.db.WithContext(ctx).Where("video_id = ?", videoID).Find(&comments).Error
|
||||||
|
return comments, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CommentRepository) IsExist(ctx context.Context, id uint) (bool, error) {
|
||||||
|
var comment Comment
|
||||||
|
if err := r.db.WithContext(ctx).First(&comment, id).Error; err != nil {
|
||||||
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CommentRepository) GetByID(ctx context.Context, id uint) (*Comment, error) {
|
||||||
|
var comment Comment
|
||||||
|
if err := r.db.WithContext(ctx).First(&comment, id).Error; err != nil {
|
||||||
|
if err == gorm.ErrRecordNotFound {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &comment, nil
|
||||||
|
}
|
||||||
51
internal/video/comment_service.go
Normal file
51
internal/video/comment_service.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package video
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CommentService struct {
|
||||||
|
repo *CommentRepository
|
||||||
|
VideoRepository *VideoRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCommentService(repo *CommentRepository, videoRepo *VideoRepository) *CommentService {
|
||||||
|
return &CommentService{repo: repo, VideoRepository: videoRepo}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CommentService) Publish(ctx context.Context, comment *Comment) error {
|
||||||
|
exists, err := s.VideoRepository.IsExist(ctx, comment.VideoID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
return errors.New("video not found")
|
||||||
|
}
|
||||||
|
return s.repo.CreateComment(ctx, comment)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CommentService) Delete(ctx context.Context, commentID uint, accountID uint) error {
|
||||||
|
comment, err := s.repo.GetByID(ctx, commentID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if comment == nil {
|
||||||
|
return errors.New("comment not found")
|
||||||
|
}
|
||||||
|
if comment.AuthorID != accountID {
|
||||||
|
return errors.New("permission denied")
|
||||||
|
}
|
||||||
|
return s.repo.DeleteComment(ctx, comment)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CommentService) GetAll(ctx context.Context, videoID uint) ([]Comment, error) {
|
||||||
|
exists, err := s.VideoRepository.IsExist(ctx, videoID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
return nil, errors.New("video not found")
|
||||||
|
}
|
||||||
|
return s.repo.GetAllComments(ctx, videoID)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user