- 登录:工号+密码走 account-service /api/login,自动登录、被踢下线回登录页 - 消息:会话列表(未读角标/免打扰/时间)、单聊群聊、文字/语音/图片/文件消息、失败重发、历史分页 - 通讯录:新的同事/我的群聊入口、按部门分组(好友 ex 字段)、搜索 - 通话:一对一语音通话(信令走 OpenIM 自定义消息 + LiveKit,token 走 /api/rtc_token) - 界面按确认效果图 m1/m2/m3 实现,主色 #3B87F5,四态视图齐全,无英文残留
4.4 KiB
4.4 KiB
畅联 · 手机端(Flutter)
公司内部通讯 App 的手机端源码。骨架配色走企业微信式办公风(主色蓝 #3B87F5),聊天手感照微信。本目录只含 Dart 源码与 pubspec.yaml,不含 android/ios 平台脚手架。
生成平台脚手架
本仓库不带 android/、ios/ 目录。在 mobile/ 目录下执行一次即可生成:
cd mobile
flutter create --platforms=android,ios .
flutter pub get
flutter run
生成后还需要按需补充平台权限声明(Flutter 不会自动加):
android/app/src/main/AndroidManifest.xml:录音(RECORD_AUDIO)、网络(INTERNET,默认有)、读写外部存储(发文件用,按 targetSdk 版本适配)。ios/Runner/Info.plist:NSMicrophoneUsageDescription(语音消息与通话)、NSPhotoLibraryUsageDescription(发图片)。
修改服务器地址
所有服务器地址集中在 lib/config.dart,改 serverHost(内网 IP/域名)和对应端口常量即可:
| 常量 | 用途 | 默认值 |
|---|---|---|
apiAddr |
OpenIM API | http://192.168.200.11:10002 |
wsAddr |
OpenIM WebSocket | ws://192.168.200.11:10001 |
livekitUrl |
LiveKit 语音通话 | ws://192.168.200.11:17880(注意已重映射,非默认 7880) |
authApiBase |
公司账号登录后端 | http://192.168.200.11:10010 |
登录接口契约(后端:任务 B-60 account-service,已上线)
1. 账号登录
POST {authApiBase}/api/login
Content-Type: application/json
{"staffNo": "工号", "password": "...", "platformID": 1}
platformID:1 = iOS,2 = Android。- 响应统一包络
{"code": 0, "msg": "", "data": {...}}(业务失败也是 HTTP 200 +code != 0,HTTP 401/400 时同样带msg)。 - 成功
data:{"userID": "...", "nickname": "...", "imToken": "...", "expireTimeSeconds": ...}userID/imToken直接传给 OpenIM SDK 的login(OpenIM 的登录 token 由后端用 OpenIM 管理端接口换取)。
- 失败:
msg会原样展示给用户。
App 登录流程:AuthApi.login → 拿到 userID/imToken → IMService.login(SDK initSDK 在 App 启动时已执行一次)→ 进主页。userID/imToken 存 shared_preferences,下次启动自动登录;SDK 回调 onUserTokenExpired / onKickedOffline 时清凭证回登录页。
2. 语音通话 token
官方样板工程的 LiveKit token 取自 open-im-chat 业务服务端(/user/rtc/get_token,端口 10008),本项目服务端裁剪时移除了 open-im-chat,由 account-service 提供等价接口:
POST {authApiBase}/api/rtc_token
Authorization: Bearer {登录返回的 imToken}
Content-Type: application/json
{"room": "房间号", "identity": "当前用户 userID"}
- 成功
data:{"token": "LiveKit 访问 token"}(App 使用config.dart中的livekitUrl作为连接地址;后端用与 livekit 容器同一对LIVEKIT_API_KEY/LIVEKIT_API_SECRET签发 HS256 JWT)。 - 后端会先拿
Authorization里的 IM token 调 OpenIMparse_token校验身份,且要求identity与 token 对应的 userID 一致。 - 通话信令(呼叫/接听/拒绝/取消/挂断)走 OpenIM 自定义消息(customType 200-204 的仅在线消息),与官方样板工程协议一致,不需要后端参与。
代码结构
lib/
main.dart 入口:主题、路由、启动页(自动登录)、被踢下线/来电处理
config.dart 服务器地址集中配置
theme.dart 颜色、字号阶梯(4 级)、间距常量(4 的倍数)
models/signaling.dart 通话信令数据模型(与官方样板一致)
utils/format.dart 时间格式化、文件大小、会话预览文案
services/
im_service.dart OpenIM SDK 封装:init/login/监听/会话列表(ChangeNotifier)
auth_api.dart 公司账号登录 + LiveKit token 的 HTTP 客户端(dio)
call_service.dart 一对一语音通话:信令 + LiveKit 房间
screens/ 登录、主页三 Tab(消息/通讯录/我的)、聊天、通话等页面
widgets/ 头像、消息气泡、输入栏、四态视图
测试账号
员工账号由管理员在 account-service 管理页批量导入(工号 + 姓名 + 初始密码),App 端不开放自助注册。联调时请管理员先导入测试名单。