后端大项目 message 部分的思考与实现| 青训营笔记

41 阅读2分钟

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

需求分析

这次青训营后端进阶班大项目的最后一个部分就是两个消息接口的实现。既然这次的大项目被称为抖音极简版,那么就非常有必要的需要包含一定的社交属性,这次的大项目给出的客户端 APP 是基于定时轮询服务端口来获取消息记录,因此,不难想到可以通过 MySQL 来存储相应的聊天记录,在用户打开聊天向服务端发出定时轮询时,我们可以通过当前用户 from_user_id 以及聊天对象,即消息接收用户 to_user_id 来从 message 表中查找信息,并按照创建时间升序排列存为切片,返回客户端。

接口说明

首先感谢青训营的工作人员及时修正了接口的说明云文档

image.png

官方接口文档分析

  1. 客户端 请求参数
    • token 在用户登录时获得,可通过解析获得 from_user_id
    • to_user_id 聊天对象user_id,通过获得朋友列表中得到
  2. 服务端 返回参数
    • status_code & status_msg 已整合入 CommonResponse 中
    • message_list 消息列表
      • id 用于标识这条消息记录的唯一id
      • to_user_id 该条消息接收者的唯一id
      • from_user_id 该条消息发出者的唯一id
      • content 该条消息内容
      • create_time 消息创建时间,用于消息排序

这里通过阅读抖声APP说明文档的评论区发现,create_time 的实际接受类型应为 int64 而非 string

根据官方接口文档及我的分析,创建相应的结构体及其方法

结构体定义

type Message struct {
   Id         int64     `json:"id"`
   FromUserId int64     `json:"to_user_id"`
   ToUserId   int64     `json:"from_user_id"`
   Content    string    `json:"content"`
   CreateTime int64     `json:"create_time"`
   CreatedAt  time.Time `json:"-"`
}

Message 主要数据库查询方法

// CreateMessage 创建聊天记录
func (m *MessageDAO) CreateMessage(msg *Message) error {
   if msg == nil {
      return errors.New("CreateMsgByFromId:" + errortype.PointerIsNilErr)
   }
   return DB.Transaction(func(tx *gorm.DB) error {
      if err := tx.Create(msg).Error; err != nil {
         return err
      }
      return nil
   })
}
// DeleteMessage 删除消息
func (m *MessageDAO) DeleteMessage(id int64) error {
   return DB.Transaction(func(tx *gorm.DB) error {
      if err := tx.Exec("DELETE FROM messages WHERE id = ?", id).Error; err != nil {
         return err
      }
      return nil
   })
}
// QueryMsgById 通过消息ID查询聊天记录
func (m *MessageDAO) QueryMsgById(id int64, msg *Message) error {
   if msg == nil {
      return errors.New("QueryMsgById" + errortype.PointerIsNilErr)
   }
   return DB.Where("id = ?", id).First(msg).Error
}
// QueryMsgListByFromIdAndToId 通过 to_user_id 和 from_user_id 来查询聊天记录列表
func (m *MessageDAO) QueryMsgListByFromIdAndToId(fromId int64, toId int64, messages *[]*Message) error {
   log.Println(fromId, " ", toId)
   if messages == nil {
      return errors.New("QueryMsgListByFromIdAndToId" + errortype.PointerIsNilErr)
   }
   if err := DB.Model(&Message{}).Where("(to_user_id = ? AND from_user_id = ?) OR (to_user_id = ? AND from_user_id = ?)", toId, fromId, fromId, toId).Order("created_at ASC").Find(messages).Error; err != nil {
      return err
   }
   return nil
}