这是我参与「第三届青训营 -后端场」笔记创作活动的的第6篇笔记
项目所用技术栈
GO GIN GORM GIN-JWT REDIS
项目亮点
- token使用GIN-JWT生成,保证token的安全性,除了登陆注册和视频流,其他接口都需要通过中间件验证token是否合法
- 点赞数据通过redis存储,每条视频都有一个score,score由视频发布时间和点赞数决定
- 用户ID和视频ID使用雪花算法生成唯一ID,密码使用MD5加密存储
- 对于sql语句使用预编译占位符填充的方法编写,一定程度上防止sql注入,gorm中interpolateParams设置为false,删去Conn到数据库中预编译的三个步骤,提高查询效率
- 视频封面使用ffmpeng进行抽取
项目层次结构
controller:为前端发送的请求提供接口并返回数据和状态码
middlewares:中间件
public:存放视频和封面到本地
respository:封装了操作数据库的增删改查方法
service:封装了较为复杂的业务逻辑
util:工具类
项目演示
视频流
点赞
喜爱列表
发布列表
评论列表
模型数据
user 主键Id
type User struct {
Id int64 `json:"id,omitempty" gorm:"column:id"`
Password string `json:"password,omitempty" gorm:"column:password"`
Name string `json:"name,omitempty" gorm:"unique_index,column:name"`
FollowCount int64 `json:"follow_count,omitempty" gorm:"column:followcount"`
FollowerCount int64 `json:"follower_count,omitempty" gorm:"column:followercount"`
IsFollow bool `json:"is_follow,omitempty" gorm:"column:IsFollow"`
Token string `gorm:"unique_index,column:token"`
}
comment 主键ID 外键UserID 和VideoID
type Comment struct {
Id int64 `json:"id,omitempty"`
UserID int64
User User `json:"user" gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
VideoID int64
Video Video `json:"user" gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
Content string `json:"content,omitempty"`
CreateDate string `json:"create_date,omitempty"`
}
video 主键ID 外键Author ID
type Video struct {
Id int64 `json:"id,omitempty"`
AuthorID int64
Author User `json:"author" gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
PlayUrl string `json:"play_url" json:"play_url,omitempty"`
CoverUrl string `json:"cover_url,omitempty"`
FavoriteCount int64 `json:"favorite_count,omitempty"`
CommentCount int64 `json:"comment_count,omitempty"`
IsFavorite bool `json:"is_favorite,omitempty"`
CreateTime time.Time `gorm:"column:create_time"`
Title string `json:"title" gorm:"column:title"`
}
粉丝
type FollowFollower struct {
gorm.Model
FollowId int64
FollowerId int64
IsFavorite bool
}
各个接口说明
feed
逻辑
根据客户端传输的latest_time作为本次视频流的起始索引,执行GetVideoList方法
GetVideoList:
- 从Redis中的查询视频的ids并根据视频的得分高低返回ids。(Redis以zset的数据结构存储视频的id)再根据ids到
- MYSQL中获取视频数据。每次请求中得分高的视频排在前面。得分由视频发布时间和点赞数决定,起始分数为发布时间,每次点赞加432分。取消则减432分
接口测试
Register
逻辑:
- 从url中获取username和password,数据库查询是否存在
- 不存在使用JWT生成token,使用雪花算法生成userID
- 将User存进数据库中,密码使用md5加密
接口测试
Login
逻辑:
- 从url中获取username和password,根据username获取token,token存在则返回userID和token,不存在则提示用户不存在
接口测试
Publish
逻辑:
- 从表单中获取title和token、文件,使用雪花算法生成videoID,根据用户名存储视频的url,mysql保存video的信息,redis以zset的形式保存video的id
接口测试
favourite
逻辑:
- 从url中获取token,vidoID,actiontype并根据token获取user数据
- actiontype为1,则为视频加分和加点赞数,并在redis中将userID存入视频的点赞列表,将videoID存入视频的喜爱列表,存入为0则减分和减点赞数,从点赞列表删去userID,从喜爱列表中删区videoID
接口测试
comment
逻辑:
- 从url中获取token和text(评论字段),videoID,ationtype,根据token获取user数据
- 如果actiontype=1则添加评论并存入数据库,如果等于0则删除评论
Follow
逻辑:
- 从url中获取关注者和被关注者、token、actiontype,先判断关注者是不是作者,如果是作者返回错误
- 根据actiontype判断是关注还是取消,如果关注则保存关注者id和被关注者id到follow表中,如果是取消则将表中的IsFavorite属性设为false