Day16-大项目实现记录 | 青训营笔记

57 阅读5分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 16 天

项目实现

技术选型与相关开发文档

开发环境:win10+go1.19+mysql8.0+ffmpeg

web框架:go-gin

数据库操作:gorm

架构设计

项目架构图:

解释如下:

1、 路由层

接收前端的的路由请求,将请求信息分发至相应的controller层的函数中

2、 controller层

解析客户端端请求中携带的参数,调用service层相关函数。返回请求结果到客户端

3、 Service层

文件上传下载逻辑具体函数的实现,接收controller中所传进来的参数。根据需要将数据传入dao层返回业务数据

4、 dao层

接收service层的参数,使用gorm包负责对mysql表的CURD操作,接收并包装操作数据库返回的数据,同时返回给上层的调用函数

数据库表结构

服务端代码结构:

tiktok:.
  go.mod
  go.sum
  main.go
  README.md
+---controller
      comment.go
      favorite.go
      follower.go
      message.go
      response.go
      user.go
      video.go
+---dao
  \---mysql
          comment.go
          favorite.go
          follower.go
          init.go
          message.go
          user.go
          user_test.go
          video.go
          video_test.go
+---mid
  |   format.go
  +---jwt
  |       auth.go
  |       jwt.go
  +---oss
  |       init.go
  \---validate
          validator.go
+---model
      comment.go
      message.go
      model.go
      user.go
      video.go
+---router
      router.go
+---service
        comment.go
        favorite.go
        follower.go
        message.go
        user.go
        user_test.go
        video.go

1、 路由层——router.go

接收前端的的路由请求,将请求信息分发至相应的controller层的函数中,需要鉴权的接口在路由与方法间加入鉴权中间件

2、 controller层

解析客户端请求中携带的参数id,调用service层相关函数得到返回得数据,对数据进行包装后c.json()响应回客户端:

user.go:

//用户注册
func Register(c *gin.Context) {}
//用户登录
func Login(c *gin.Context) {}
// UserInfo 获取用户信息
func UserInfo(c *gin.Context) {}

video.go:

//投稿,上传视频接口
func Upload(c *gin.Context) {}
//获取喜欢列表
func List(c *gin.Context) {}
//视频流接口
func Feed(c *gin.Context) {}

favorite.go:

//点赞操作
func FavoriteAction(c *gin.Context) {}
//点赞列表
func FavoriteList(c *gin.Context) {}

comment.go:

//评论操作
func CommentAction(c *gin.Context) {}
//评论列表
func CommentList(c *gin.Context) {}

follower.go:

//关注操作
func RelationAction(c *gin.Context) {}
//关注列表
func FollowList(c *gin.Context) {}
//粉丝列表
func FollowerList(c *gin.Context) {}
//朋友列表
func FriendList(c *gin.Context) {}

message.go:

//发送消息
func MessageAction(c *gin.Context) {}
//获取聊天记录
func MessageChat(c *gin.Context) {}

接口实现步骤:以获取关注列表为例:

func FollowerList(c *gin.Context) {
   userId, _ := c.Get("id")
   followerMessage, err := service.FollowerList(userId)
   if err != nil {
      log.Println("fail", err)
      return
   }

   var userList = make([]User, 0, 10)
   for _, follower := range followerMessage {
      isFollower := mysql.GetIsFollower(userId, follower.Id)
      user := User{
         Id:              follower.Id,
         Name:            follower.Username,
         FollowCount:     follower.FollowCount,
         FollowerCount:   follower.FollowerCount,
         Avatar:          follower.Avatar,
         BackgroundImage: follower.BackgroundImage,
         Signature:       follower.Signature,
         TotalFavorited:  follower.TotalFavorited,
         WorkCount:       follower.WorkCount,
         FavoriteCount:   follower.FavoriteCount,
         IsFollow:        isFollower,
      }
      userList = append(userList, user)
   }
   c.JSON(http.StatusOK, FollowListResponse{
      StatusCode: 0,
      StatusMsg:  "success",
      UserList:   userList,
   })
}

3、 Service层,以获取关注列表为例

接收controller中所传进来的参数。根据需要将数据传入dao层返回用户信息列表,这里service层主要用于解耦

func FollowerList(userId interface{}) (followerMessage []model.User, err error) {
   return mysql.GetFollowerList(userId)
}

4 、dao层

接收service层的参数,使用gorm包负责对mysql表的CURD操作,接收并包装操作数据库返回的数据,同时返回给service层的调用函数

// GetFollowerList 获取粉丝用户
func GetFollowerList(userId interface{}) (followMessage []model.User, err error) {
   userIds := make([]int, 0)
   err = DB.Transaction(func(tx *gorm.DB) error {
      if err = tx.Table("followers").Where("to_user_id = ? AND state = ?", userId, 1).
         Select("from_user_id").Find(&userIds).Error; err != nil {
         log.Println("Fetch error", err)
         return err
      }
      for _, userId := range userIds {
         var user model.User
         user, err = GetUserMessageById(userId)
         followMessage = append(followMessage, user)
      }
      return nil
   })
   if err != nil {
      return nil, err
   }
   return followMessage, nil
}

测试结果

1、基础接口--所有接口功能均已实现

未登录状态,返回按投稿时间倒序的视频列表,视频数一次获取15个,通过用户名和密码进行登录,登录成功后返回用户 id 和权限 token。新用户注册时提供用户名,密码即可,用户名需要保证唯一。创建成功后返回用户 id 和权限token拉取当前登录用户的全部信息,并存储到本地。用户信息包含 id、昵称,如果实现社交部分的功能,还会返回关注数和粉丝数。

登录状态下,登录用户选择视频上传,完成信息填充后点击发布,发布完成会弹出发布完成提示信息并自动关闭投稿页面,打开个人或他人主页,会立即发布列表接口,直接列出用户所有投稿过的视频。

2、互动接口--所有接口功能均已实现

登录状态下,登录用户可对视频的点赞和取消点赞操作,打开个人或他人主页,会立即点赞列表接口,直接列出用户所有点赞过的视频。

登录状态下,点击视频中得评论区图标会查看视频的所有评论,按发布时间倒序,用户可对视频进行评论,输入评论内容并发布,会立马获取到自己得评论展示于评论首部,长按该评论出现删除按钮可删除自己的评论。因为客户端不会重新拉取评论列表,所以删除后不会立马消失,但确实已删除。

暂时无法在飞书文档外展示此内容

3、社交接口--所有接口功能均已实现

登录状态下,在首页点击头像上的+号 和用户个人页点击关注,都会调用关注接口执行关注和取消关注的逻辑,在个人页点击 粉丝/关注,能够打开关注页面,会立即调用接口拉取关注用户和粉丝用户列表。

点击下方消息页面,会立即请求接口,获取可聊天朋友列表,朋友即互相关注得用户,并且会带着和该用户的最新的一条消息。点击任意用户,进入详细聊天页面。在该页面下会定时轮询消息查询接口,获取最新消息列表。输入消息点击发送,会通过消息发送接口发送该消息