青训营总结|青训营笔记

162 阅读3分钟

这是我参与「第三届青训营 - 后端场」笔记创作活动的第5篇笔记

个人总结

在本次的青训营活动中,学到了包括Go语言,互联网大厂内部的部分最佳实践,还有较为基础的计算机网络,数据结构与算法等课程,学到的是较为宽泛的内容,希望自己在暑假中能继续学习,夯实基础。

项目

技术选型

本次的项目主要根据提供的接口进行实现,使用了Gin+Jwt+Gorm+Mysql+OSS开发。

负责的部分

负责Feed流以及Video相关的接口

DB层负责操纵数据库

package db

import (
   "context"
   "gorm.io/gorm"
)

type Video struct {
   gorm.Model
   AuthorId     int64  `gorm:"column:author_id;type:bigint(20)not null;comment:作者id"`
   PlayUrl      string `gorm:"column:play_url;type:varchar(255)not null;comment:视频播放地址"`
   CoverUrl     string `gorm:"column:cover_url;type:varchar(255)not null;comment:视频封面地址"`
   CommentCount int64  `gorm:"column:comment_count;type:int(20);default:0;comment:评论数"`
   Title        string `gorm:"column:title;type:varchar(255)not null;comment:视频标题"`
}

func (v Video) TableName() string {
   return "video"
}

// QueryVideoByAuthor 根据作者ID查询视频集
func QueryVideoByAuthor(ctx context.Context, authorId int64) ([]*Video, error) {
   var res []*Video
   if err := DB.WithContext(ctx).Where("author_id = ?", authorId).Find(&res).Error; err != nil {
      return nil, err
   }
   return res, nil
}

// CreateVideo 插入视频
func CreateVideo(ctx context.Context, video Video) error {
   if err := DB.WithContext(ctx).Create(&video).Error; err != nil {
      return err
   }
   return nil
}

// QueryVideoById 根据ID查询视频
func QueryVideoById(ctx context.Context, videoId int64) (*Video, error) {
   var res *Video
   if err := DB.WithContext(ctx).Where("id = ?", videoId).Find(&res).Error; err != nil {
      return nil, err
   }
   return res, nil
}

Service层负责调用dal层 进行具体的业务开发

package service

import (
   "context"
   "io/ioutil"
   "sync"
   "tiktok/src/dal/db"
   "tiktok/src/errno"
   "tiktok/src/handlers"
   "tiktok/src/utils/ossUtil"
)

type VideoService interface {
   CreateVideo()
}

var (
   videoService     *VideoServiceImpl
   videoServiceOnce sync.Once
)

func VideoServiceInstance() *VideoServiceImpl {
   videoServiceOnce.Do(
      func() {
         videoService = &VideoServiceImpl{}
      })
   return videoService
}

type VideoServiceImpl struct {
}

func (this *VideoServiceImpl) CreateVideo(ctx context.Context, req handlers.PublishParams) (err error) {
   userId := req.UserId
   title := req.Title
   file := req.Data
   fileHandle, err := file.Open()
   if err != nil {
      return errno.ServiceErr.WithMessage("打开文件错误")
   }
   defer fileHandle.Close()
   fileByte, err := ioutil.ReadAll(fileHandle)
   url, err := ossUtil.UploadFile(file.Filename, fileByte)
   if err != nil {
      return errno.ServiceErr.WithMessage("上传失败")
   }
   //TODO 需要更改封面URL
   err = db.CreateVideo(ctx, db.Video{
      AuthorId: userId,
      PlayUrl:  url,
      CoverUrl: url,
      Title:    title,
   })
   if err != nil {
      return errno.ServiceErr.WithMessage("发布失败")
   }
   return nil
}

func (this *VideoServiceImpl) GetVideosByAuthor(ctx context.Context, userId int64) (list []*db.Video, err error) {
   list, err = db.QueryVideoByAuthor(ctx, int64(userId))
   if err != nil {
      return nil, errno.ServiceErr.WithMessage("查询失败")
   }
   return list, nil
}

// GetVideoById 根据id获取Video
func (this *VideoServiceImpl) GetVideoById(ctx context.Context, id int64) (videoInfo *handlers.VideoInfo, err error) {
   video, err := db.QueryVideoById(ctx, id)
   if err != nil {
      return nil, err
   }
   if video != nil && video.ID == 0 {
      return nil, errno.ServiceErr.WithMessage("视频不存在")
   }
   user, err := db.QueryUserById(ctx, video.AuthorId)
   if err != nil {
      return nil, errno.ServiceErr.WithMessage("用户不存在")
   }

   videoInfo = &handlers.VideoInfo{
      ID: int64(video.ID),
      Author: handlers.UserInfo{
         ID:            int64(user.ID),
         UserName:      user.UserName,
         FollowCount:   user.FollowCount,
         FollowerCount: user.FollowerCount,
         IsFollow:      false,
      },
      PlayUrl:      video.PlayUrl,
      CoverUrl:     video.CoverUrl,
      CommentCount: video.CommentCount,
      Title:        video.Title,
   }
   return videoInfo, nil
}

func (this *VideoServiceImpl) CheckVideoById(ctx context.Context, id int64) bool {
   video, err := db.QueryVideoById(ctx, id)
   if err != nil {
      return false
   }
   if video != nil && video.ID == 0 {
      return false
   }
   return true
}

Controller层进行用户的交互 还有待继续开发

package controller

import (
   "github.com/gin-gonic/gin"
   "net/http"
   "tiktok/src/constants"
   "tiktok/src/errno"
   "tiktok/src/handlers"
   "tiktok/src/service"
   "tiktok/src/utils/jwt"
)

// Publish 发布视频
func Publish(c *gin.Context) {
   claims := jwt.ExtractClaims(c)
   userID := int64(claims[constants.IdentityKey].(float64))
   title := c.PostForm("title")
   file, err := c.FormFile("data")
   if err != nil {
      panic(err)
   }
   err = service.VideoServiceInstance().CreateVideo(c, handlers.PublishParams{
      Data:   file,
      UserId: userID,
      Title:  title,
   })
   if err != nil {
      panic(errno.ServiceErr.WithMessage("创建失败"))
   }
   c.JSON(http.StatusOK, &handlers.UploadResponse{
      Response: handlers.Response{
         StatusCode: 200,
         StatusMsg:  "成功",
      },
   })
}

//TODO PublishList
//func PublishList(c gin.Context) {
// token := c.Query("token")
// userId := c.Query("user_id")
//
//}

在本次青训营的学习中,认识了很多大佬,也学到了很多相关的知识,一起进步,快乐的青训营下次债见