这是我参与「第三届青训营 - 后端场」笔记创作活动的第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")
//
//}
在本次青训营的学习中,认识了很多大佬,也学到了很多相关的知识,一起进步,快乐的青训营下次债见