功能深度解析(上):账号体系、个人资料与 avatar 的三次迭代
2026/6/25 15:51:35 网站建设 项目流程

海狸IM 功能深度解析(上):账号体系、个人资料与 avatar 的三次迭代

写在前面:为什么从账号和资料讲起

IM 产品第一眼看到的是聊天窗口,但底层第一条链路永远是:谁在用、资料长什么样、头像和媒体怎么存

海狸 2.0 是自建账号 + 好友模型 + 双端客户端,没有企业通讯录树,也没有官方 SaaS 公共服。用户在你部署的beaver-server上注册,拿到userId之后,才能加好友、进群、走 OAuth、收 Webhook 通知。

把账号和资料讲清楚,后面聊消息、开放接入才不会飘。尤其avatar / fileUrl 我来回改了三次——这不是小事,它直接决定了 OAuth 能不能对外透头像、Webhook 能不能塞外链图片。这篇会把来龙去脉写透。


1. 账号体系:自建用户,完整注册登录链路

1.1 产品模型

海狸的账号就是服务端user模块里的UserModel,核心字段包括userIdnickNameavataremail/phone等。注册完成后即拥有全局唯一的userId,后续好友、群、OAuth、机器人身份都挂在这个 id 上。

服务端还区分用户类型(普通用户 / 推送 Bot / 智能机器人 Robot),2.0 开放接入里群 Webhook 用的 Bot 也走同一套 user 表,只是userType不同——这块在 51 号下篇展开。

1.2 注册与登录方式(2.0)

能力PCFlutter说明
邮箱注册邮箱验证码
手机注册短信验证码,需服务端配置短信通道
邮箱 + 密码登录办公场景最常用
手机 + 密码登录
邮箱验证码登录免密
找回 / 重置密码邮箱或手机验证
扫码登录OAuth 或 PC 快捷登录场景

1.3 一条典型的注册链路

从用户视角,邮箱注册可以概括为:

打开客户端 → 选邮箱注册 → 收验证码 → 设密码 → 注册成功 → 自动或手动登录 → 拿到 Token / 建立 WS 连接 → 进入消息主页

服务端侧:auth模块校验验证码 →user模块创建 UserModel → 返回登录态。之后客户端会拉个人资料、走 datasync 同步好友与会话摘要——账号一旦建好,后面所有模块都认这个 userId

1.4 扫码登录在 2.0 里的位置

扫码不只是「图省事」,还是OAuth2 第三方接入的标配交互:PC 或第三方 Web 展示二维码,用户用海狸 App 扫,在beaver-oauth授权页确认,服务端完成 Token 签发。

二维码状态一般经历:待扫 → 已扫 → 已确认 / 过期。具体接口见文档站 OAuth 章节;和 51 号下篇的开放能力是一套链路。

1.5 账号安全与设备管理

能力PCFlutter说明
修改登录密码✅ 设置中心🔶Flutter 2.1 对齐 PC
已登录设备列表🔶展示 UA、在线状态
远程踢设备下线🔶踢掉其他端
退出登录

2.0 在PC 独立设置中心把改密、设备管理做全了;移动端能登录、能聊天,安全类设置弱一些,这在 2.1 规划里会对齐。设备与会话安全可以单独再开一篇,本篇点到为止。

1.6 2.0 明确不做的

  • ❌ 企业组织架构 / 部门通讯录树
  • ❌ 绑定微信 / 钉钉等第三方公共 IM 账号
  • ❌ 官方运营的公共账号池

要的是私有化自建账号,不是 SaaS 大号体系。加人靠搜用户名群成员,这是产品定位,不是缺功能。


2. 个人资料:能改什么、双端怎么改

2.1 资料字段

PCFlutter说明
头像上传后全局展示
昵称会话列表、气泡、好友详情
个性签名好友详情可见
性别等扩展字段资料页编辑
查看他人资料好友详情、群成员

改完昵称或头像后,好友端、群成员列表、OAuth 对外接口读到的都是新版本。UserModel 带version字段,资料变更会递增,供 datasync 做增量同步。

2.2 用户设置:PC 的「换电脑不丢配置」

PC 2.0独立设置中心有一项容易被忽略的能力:部分用户设置 JSON 写入服务端

典型场景:你在公司电脑自定义了快捷键,回家用自己 PC 登录同一账号,设置从服务端拉下来,不用重配。Flutter 侧有通用设置(通知、缓存等),和 PC 完全对齐的项还在迭代。

这类「账号 + 设置跟用户走」的设计,和后面换设备 datasync 补消息是同一产品思路:数据在服务端有权威副本,客户端是缓存 + 展示


3. 头像与文件:从上传到落库的真实路径

3.1 客户端怎么传头像

双端流程一致,可以概括成四步:

选图 → 调 file 服务 upload → 响应里拿 fileUrl → 调 user 接口更新 avatar 字段

PC 端beaver-desktop个人资料页):上传成功后直接把uploadResult.fileUrl赋给表单里的avatar,保存时提交给updateUserInfo

Flutter 端profile/bloc.dart):uploadFileApi返回fileUrl,再updateUserInfo({'fileName': fileUrl})——字段名历史原因还叫fileName,值实际是完整 URL

3.2 file 服务返回什么

file_api.api里上传接口的响应结构:

typeFileRes{FileKeystring`json:"fileKey"`FileURLstring`json:"fileUrl,optional"`OriginalNamestring`json:"originalName"`FileInfo*FileInfo`json:"fileInfo,optional"`}

也就是说:上传后服务端既知道 fileKey(内部键),也会拼出 fileUrl(对外可访问地址)。预览路由是GET /api/file/preview/:fileKey,但落库到用户表、消息体里,2.0 选的是存 URL

3.3 服务端 UserModel 长什么样

beaver-server/app/user/user_models/user_module.go

typeUserModelstruct{UserIDstring`gorm:"size:64;uniqueIndex" json:"userId"`UserTypeint8`gorm:"default:1;index" json:"userType"`NickNamestring`gorm:"size:32;index" json:"nickName"`Avatarstring`gorm:"size:256;default:https://.../file/preview/xxx.png"`// 头像URLAbstractstring`gorm:"size:128" json:"abstract"`// ...Versionint64`gorm:"not null;default:0;index" json:"version"`}

注释写得很直白:Avatar 就是 URL。默认值也是一个可访问的 preview 地址,保证新用户注册后头像不为空。

3.4 聊天消息里的媒体:同一套 fileUrl

消息体定义在common/models/ctype/msg.go,图片、视频、文件、语音等统一用fileUrl,注释均为「完整 URL」:

typeImageMsgstruct{FileUrlstring`json:"fileUrl"`// 图片完整 URL// ...}typeVoiceMsgstruct{FileUrlstring`json:"fileUrl"`// 语音文件完整 URLDurationint`json:"duration,omitempty"`}

客户端自己发的图:upload → 填自己的 preview URL。
后面 Webhook 机器人发的图:外部系统直接填 https 外链。
协议层都认fileUrl,这是 2.0 刻意保持的一致。


4. 开发反思:avatar 我改了三次

这是做海狸 IM 过程中印象最深的一段设计反复,单独拎出来说——因为背后不是「技术洁癖」,而是产品阶段变了,约束就变了

4.1 第一次:数据库 avatar 直接存完整 URL

最早的做法最直觉:UserModel.Avatar 存 https 开头的完整地址

好处:

  • 客户端<img :src="avatar">零转换,会话列表、资料页、消息 Sender 同一套渲染
  • 管理后台beaver-manager用户 360 视图直接展示
  • 以后做 OAuth,用户信息接口把 avatar 原样返回,第三方 OA 也能直接展示

当时想法很简单:IM 里头像就是给人看的,少一层转换,少一类 bug

4.2 第二次:改成文件唯一 id,想把鉴权做严

跑通双端聊天、file 服务上线之后,我又动念头:能不能库里只存 fileKey / fileId,访问时走带登录态的 preview 接口?

动机很实在:

  • 私有化客户有的要求文件链接不能永久裸奔
  • 审计、过期、权限都想挂在 file 网关
  • 头像和消息媒体走同一套「id → 鉴权 → 取流」,架构上更「干净」

那段时间客户端改过一版:资料里存 id,展示前再拼 preview 路径或换临时 URL。从纯后端视角,这更「正确」。

4.3 第三次:又改回完整 URL——开放能力逼的

第三次改回去,不是因为 id 方案错了,而是 2.0 要上OAuth2群 Webhook 推送,两条链路都和「外部世界」打交道:

OAuth 侧:
第三方 OA 调用户信息接口,期望 JSON 里avatar能直接<img>的地址。若只给 fileKey,OA 还得对接你的 file API、处理登录态——接入文档会厚一倍,集成方会直接放弃。

Webhook 侧:
bot_public.api里,机器人发 Markdown 配图、发图片、发链接卡片,字段全是url

typeBotImageContent{URLstring`json:"url"`// 图片完整 URL}typeBotMarkdownContent{Imagestring`json:"image,optional"`// 配图 URL}typeBotLinkContent{ImageURLstring`json:"imageUrl,optional"`// 链接配图 URL}

Jenkins、Prometheus、自研脚本不会先调你的 upload 拿 fileKey。它们手里只有 Grafana 截图链接、CDN 地址。若用户表和消息协议强制只认 id,集成方就得写「下载外链 → 再 upload 到你这」——告警 5 分钟一条的场景,file 服务很快被 proxy 打满。

所以 2.0 最终取舍是:

层级存什么原因
UserModel.avatar完整 URL双端渲染简单;OAuth 可直接透出
消息体 fileUrl完整 URL客户端 upload 后填 URL;Webhook 可塞外链
file 服务fileKey + 存储自有文件仍走 upload;preview 路由保留
鉴权加强(若要做)在 preview 网关加策略例如短期签名,而不是逼全世界改 id

用一张图概括三次迭代:

┌─────────────┐ │ 完整 URL │ ← 第一版:简单直给 └──────┬──────┘ ↓ 想要文件鉴权 ┌─────────────┐ │ fileKey/id │ ← 第二版:网关统一控 └──────┬──────┘ ↓ OAuth + Webhook 要对外互操作 ┌─────────────┐ │ 完整 URL │ ← 第三版:回到 URL,鉴权后置 └─────────────┘

体会:IM 一旦做开放接入,内部一致性和外部互操作经常打架。没有银弹,只有当前版本的 trade-off。以后若加强文件安全,我会在file preview 层做签名或 Referer 校验,而不是让 Jenkins 先学一遍海狸 fileKey 协议。


5. 资料改完,其他端怎么知道

用户改头像或昵称后,在线端通过WebSocket tableUpdates感知变更,离线端靠datasync 增量补。好友详情、会话列表里的 Sender 信息会随 userversion更新——你不需要手动「刷新好友资料」。

这条链路和 46 / 47 号文里的消息 sync 是同一套思路:WS 通知有变更 → 客户端按模块拉增量。资料模块属于「用户域」,不是聊天 seq,但产品体验一致:换手机登录,头像还是新的

好友关系本身走getSyncFriendsgetSyncFriendVerifies等接口,52 号讲好友与私聊时会展开,本篇只建立概念:账号和资料是 IM 的地基,sync 保证地基在多端一致


6. 本篇小结与下篇预告

本篇讲了什么:

  • 海狸 2.0自建账号的注册登录、安全设备、扫码在 OAuth 里的位置
  • 个人资料双端能改什么、PC 设置云端同步
  • file 上传 → avatar / fileUrl 落库的真实路径与源码字段
  • avatar 三次迭代的来龙去脉:最终为 OAuth 与 Webhook 回到完整 URL

刻意没写的(留给后面):

计划篇主题
51(下篇)OAuth2 登录 + 群 Webhook
52好友与私聊:会话、消息类型、已读撤回
53群聊:禁言、入群审批、@ 成员
54表情与动态
55音视频、通知中心
56beaver-manager 运营与审核

「有没有、双端支不支持」仍以48 号文表格为准;系列文是一块讲透 + 开发体会,不是把 48 复制粘贴拆成十篇。


相关链接

项目源码:

  • 后端源码:https://github.com/wsrh8888/beaver-server
  • 移动端Flutter源码:https://github.com/wsrh8888/beaver-flutter
  • PC端源码:https://github.com/wsrh8888/beaver-desktop.git
  • 后台管理系统源码:https://github.com/wsrh8888/beaver-manager
  • 开放平台门户源码:https://github.com/wsrh8888/beaver-open
  • OAuth 授权登录页源码:https://github.com/wsrh8888/beaver-oauth

学习资源:

  • 在线文档:https://wsrh8888.github.io/beaver-docs/

核心教学视频:

  • 本地搭建教程合集:https://space.bilibili.com/269553626/lists/6075764?type=season
  • 服务器部署教程合集:https://space.bilibili.com/269553626/lists/6075828?type=season

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询