功能实现
用户注册、登录
- 用户注册 user/register 必填邮箱和密码
- 邮箱发送验证码 email/code 验证码有效期5min,存在redis中
- 用户输入验证码后调用注册接口,验证成功后用户注册且返回token
- 用户登录 user/login
用户表 user
用户好友
用户申请好友
- 申请好友 post-friend/apply
- 好友申请列表 get-friend/apply/list
- 同意好友申请 post-friend/approve
- 好友列表 post-friend/list
- 是否好友 get-friend/check
- 删除好友 post-friend/delete
用户申请表 user_apply
好友表 friend
消息
消息发送
问题
go
// 如何优雅实现根据msgType将Body转换为TextMsgBody/ImageMsgBody
type ChatMsgReq struct {
g.Meta `path:"/chat/msg" method:"post" tags:"Chat" summary:"发送消息"`
RoomId string `json:"roomId" description:"房间id" v:"required#房间id必填"`
MsgType int `json:"msgType" description:"消息类型" v:"required#消息类型必填"`
Body interface{} `json:"body" description:"消息体" v:"required#消息体必填"`
}
难点
- 请求参数的body根据请求参数msgType转换成对应的消息类型body,踩了json.Number转换的坑,gpt输出都是什么float,int类型,详见(ParseBody方法)
- 将json数据格式插入到数据库,因为orm的数据类型是string,导致
""
,就会报错,需要自己更换成"{}"
,当然这也是因为自己没有过滤空值。最后填充扩展消息的时候需要自己主动序列化,这样插入消息才正确,但是取出的转换还没有写 - 更新消息的时候,忘记主键重复(Where),空值过滤(OmitEmpty)等条件
- 注意事务,消息插入和更新,如果失败,则同时回滚数据
会话列表
- 保存或更新会话列表
- 获取会话列表
- 更新用户已读时间
注意
- 保存会话列表,根据userId,roomId建立
- 返回会话id、房间id、用户已读时间、会话头像(好友头像/群头像)、会话内消息最后更新时间、会话最新消息id创建时间、修改时间、消息未读数、消息内
- 会话表更新时机,发送消息成功时更新会话表,根据userId、roomId找到会话记录,更新会话最新消息id及其创建时间
- 客户端进入会话列表,更新会话表用户已读时间
二级缓存
缓存用户/房间信息,需要加上定时更新逻辑
目前定时更新逻辑还没有加上
联系人
联系人页面设计
好友 - 返回好友信息 - 根据好友id查询用户信息 - 根据用户信息 - 查询房间信息 - 根据房间信息查找会话信息 没有则创建
群 - 返回房间信息 - 包装成会话model - 根据房间信息查找会话信息 没有则创建
联系人查找设计
找好友 - 输入好友名字 - 后台根据名字进行模糊查询 - 返回好友列表(UserModel) - 数据量不大无需分页
找群聊 - 输入群名字 - 后台根据名字进行模糊查询 - 返回群聊列表(RoomModel) - 数据量不大无需分页
用户申请加入群聊 - 向群中的群主/管理员发送申请 - 存在userApply表中 - 数据量不大无需分页
群主/管理员同意用户添加群成员 - 修改userApply表中的数据,所有人均同意申请 - 在groupMember中增加该用户 - 创建该用户的会话