> 本插件APP端需要HBuilderX 3.6.9 及其以上版本支持,微信小程序和网页端需要HBuilderX 3.6.4 及其以上版本支持。 # 简介 uni-im是云端一体的、全平台的、免费的、开源即时通讯系统。 - 基于uni-app,App、小程序、web全端兼容 - 基于uniCloud,前后端都使用js开发 - 基于[uni-push2](https://uniapp.dcloud.net.cn/unipush-v2.html),专业稳定的全端推送系统 - 基于[uni-id](https://uniapp.dcloud.net.cn/uniCloud/uni-id-summary.html),完善的账户体系 案例:打开[插件市场](https://ext.dcloud.net.cn/plugin?id=55),点击咨询作者按钮 下载地址:[https://ext.dcloud.net.cn/plugin?name=uni-im](https://ext.dcloud.net.cn/plugin?name=uni-im) ## 特点优势 - 全端可用 - App端支持nvue,更好的长列表性能。list组件性能优势[详情参考](https://uniapp.dcloud.net.cn/component/list.html) - 智能本地缓存,更快的历史消息加载速度,更小的网络请求压力 - 中心化响应式数据管理,切换会话不重头加载数据,更流畅的体验 - App端聚合多个手机厂商推送通道,app不在线也可以收到消息 ## 版本计划 ### 已上线 - 应用内嵌入uni-im,使用户方便、实时的与App运营者互动,咨询问题、反馈意见、进行投诉。 - 可发送文字、图片、音频、视频、代码、任意文件 - im交友场景:群聊、好友关系 ### 后续计划 1. 通信方式扩展:音频通话、视频通话 2. 细节完善:聊天记录识别电话邮件、消息删除和批删、消息回复、消息转发和批转、消息撤回、勿扰设置、会话置顶、留言转文字、图片提取文字 3. 客服场景:管理端支持座席 优先开发哪些,取决于开发者的反馈。同时也欢迎开发者共建这个开源项目。 > uni-im相关功能建议或问题交流,暂时请加QQ群号:[854520009](https://qm.qq.com/cgi-bin/qm/qr?k=DJNSajXAYHnYcr9pouOfxF9Rwwl1AJHc&jump_from=webapi&authKey=HZ1fG58Eudp3o0GCoyx1/UPMY9Fv1sGT5jdqYqPJlTGT0XVUip3Bk8E+UyToQOMo)。后续uni-im支持群聊后会废除QQ改为uni-im。 ### 已知bug - Mac端Safari浏览器,消息列表界面滚动到顶部无法自动加载历史消息 # 快速部署体验 ## 前提条件 1. 开通uniCloud并创建服务空间 [控制面板](https://unicloud.dcloud.net.cn/) 2. 开通`uni-push2.0`[详情参考](https://uniapp.dcloud.net.cn/unipush-v2.html#%E7%AC%AC%E4%B8%80%E6%AD%A5-%E5%BC%80%E9%80%9A) ## 体验步骤 1. 打开`uni-im`插件下载地址:[https://ext.dcloud.net.cn/plugin?name=uni-im](https://ext.dcloud.net.cn/plugin?name=uni-im) 2. 点击`使用HBuilderX导入示例项目` 3. 按提示,通过云服务空间初始化向导部署项目(注意:选择绑定的服务空间,须在uni-push2.0的[web控制台](https://dev.dcloud.net.cn/pages/app/push2/info)关联) 4. `运行项目`到2个不同的浏览器,因为在同一个浏览器打开相同网络地址(ip或者域名)的uni-im项目,socket会相互占线。 所以需要使用两个浏览器(或者使用浏览器`打开新的无痕式窗口`功能充当第二个浏览器)分别`注册账号并登录`, 到此部署已经结束 5. 向对应的用户发起会话,通过访问路径:`/uni_modules/uni-im/pages/chat/chat?user_id=` + `对应的用户id` 即可 ## 部署到自己的项目 1. 打开`uni-im`插件下载地址:[https://ext.dcloud.net.cn/plugin?name=uni-im](https://ext.dcloud.net.cn/plugin?name=uni-im) 2. 点击`使用HBuilderX导入插件`,选择你的项目,点击确定(同时会自动导入依赖的uni_modules`uni-id-pages`)按提示操作自动配置`pages.json` 3. 打开项目根目录的App.vue文件,初始化uni-id-pages和uniIm模块 示例如下: ```html ``` 4. 启用Vuex并引入uni-im的store - 打开项目根目录的main.js文件启用Vuex ```js import App from './App' import store from './store' // #ifndef VUE3 import Vue from 'vue' Vue.config.productionTip = false Vue.prototype.$store = store App.mpType = 'app' const app = new Vue({ store, ...App }) app.$mount() // #endif // #ifdef VUE3 import {createSSRApp} from 'vue' export function createApp() { const app = createSSRApp(App) app.use(store) return {app} } // #endif ``` - 项目根目录创建文件夹store,并在此目录下新建入口文件`index.js`引入uni-im的store ```js // 文件路径:/store/index.js import uniIm from '@/uni_modules/uni-im/common/store' // #ifndef VUE3 import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ modules: { uniIm }, strict: true }) // #endif // #ifdef VUE3 import {createStore} from 'vuex' const store = createStore({ modules: { uniIm } }) // #endif export default store ``` 5. 账号打通 uni-im经常用于嵌入其他App中,成为其中的一个模块。比如客服模块。这就涉及现有应用和uni-im的账户打通问题。 uni-im的账户体系是uni-id的。如果开发者的现有应用要接入uni-im,但账户体系并不在uni-id里,或使用的是老版uni-id,就需要参考本章节打通账户。 - 基于`uni-id-pages`的项目,直接登录即可,无需额外打通工作。 - 基于`uni-id-co`的项目,需要在登录成功和用户信息更新时,同步更新uniId store内的当前用户信息(uni-im显示当前用户头像、昵称时会用到)示例代码: ```js //导入uniCloud客户端账户体系,用户信息状态管理模块 import {mutations as uniIdMutations} from '@/uni_modules/uni-id-pages/common/store.js'; await uniIdMutations.updateUserInfo() ``` - 基于老版uni-id(版本号:3.x) 开发的项目,需要如下改造: 1. 在登录成功和token续期后,绑定当前账号与设备推送标识的关联关系。示例代码: ```js const uniIdCo = uniCloud.importObject("uni-id-co", {customUI: true}) uni.getPushClientId({ success: async function(e) { console.log(e) let pushClientId = e.cid let res = await uniIdCo.setPushCid({ pushClientId }) console.log('getPushClientId', res); }, fail(e) { console.error(e) } }) ``` 2. 在登录成功和用户信息更新时,同步更新uniId store内的当前用户信息(uni-im显示当前用户头像、昵称时会用到)示例代码: ```js //导入uniCloud客户端账户体系,用户信息状态管理模块 import {mutations as uniIdMutations} from '@/uni_modules/uni-id-pages/common/store.js'; await uniIdMutations.updateUserInfo() ``` - 客户端是uni-app的,但服务器不是uniCloud的情况。需开通uniCloud,然后在客户端通过uni-im-co的loginWithJWT方法实现联登,因内容较多,需另见[文档](#uniImCoLoginWithJWT)。 - 客户端如果不是uni-app的,如果是网页,可iframe内嵌。如果是app,可嵌入[uni小程序sdk](https://nativesupport.dcloud.net.cn/README) 6. 确保账户对接成功后,打开“用户列表页”,路径:`/uni_modules/uni-im/pages/userList/userList`可以看到所有的注册用户(默认仅登录的账号为超级管理员才有权限访问,你也可以根据自己的业务需求修改`uniCloud/database/uni-id-users.schema.json`配置权限[更多详情](https://uniapp.dcloud.net.cn/uniCloud/schema.html#permission)) 7. 点击某个用户,会自动创建与该用户的会话,并打开“聊天对话页”(路径:`/uni_modules/uni-im/pages/chat/chat`),然后就可以开始聊天了。 8. 还可以导入uni-im的示例项目作为管理员端与用户聊天。 9. 如果你是2个不同appId的应用相互通讯(比如:淘宝的买家端和卖家端通讯)的场景,请打开聊天对话文件(路径:`/uni_modules/uni-im/pages/chat/chat`)搜索`data.appId = this.systemInfo.appId`修改`this.systemInfo.appId`为相对的appId **补充:**(基于uni-id-pages开发的项目可忽略) 为了实现用户退出登录后,不再收到im消息,需要在执行退出登录时同步状态给uni-id-pages。示例代码如下: ```js import {mutations as uniIdMutations} from '@/uni_modules/uni-id-pages/common/store.js' uniIdMutations.logout() ``` ## 限制普通用户向其他用户发起会话 客服场景下,我们希望管理员客服可以向任意用户发起会话。而普通用户的会话对象只能是客服。 - 客户端限制 删除或隐藏“用户列表页”和“会话列表页”,仅保留“聊天对话页”。并绘制按钮,如:“联系客服”,点击后打开“聊天对话页” 逻辑代码如下: ```js uni.navigateTo({ url:'/uni_modules/uni-im/pages/chat/chat?user_id=' + 对应的用户id }) ``` - 服务端限制 1. 添加`uni-im`配置文件,打开:`/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/`;新建`uni-im`文件夹和`config.json`文件,示例如下: ```json { "admin_uid":false } ``` 2. 配置`admin_uid`的值为管理员客服的user_id(支持多个以数组的形式指定),如果会话双方均不属于此域则无法通讯。不配置或为false则表示不限制。 # 开发文档 ## 目录结构
├─uni_modules 存放[uni_module](/uni_modules)规范的插件。
│ ├─其他module
│ └─uni-im
│ ├─uniCloud
│ │ ├─cloudfunctions 云函数目录
│ │ │ └─uni-im-co 集成调用uni-im方法的云对象
│ │ └─database
│ │ ├─uni-im-conversation.schema.json 聊天会话表的表结构
│ │ └─uni-im-msg.schema.json 聊天消息表的表结构
│ ├─common
│ │ ├─msgManager.js 消息管理类库
│ │ ├─store.js 状态管理
│ │ ├─utils.js 工具类库
│ │ └─uni-im-storage.js 封装storage操作库
│ ├─components
│ │ └─uni-im-msg 显示聊天消息气泡组件
│ ├─pages
│ │ ├─chat
│ │ │ └─chat.nvue 聊天对话页
│ │ ├─index
│ │ │ └─index.nvue 会话列表页
│ │ └─userList
│ │ └─userList.vue 用户列表页
│ ├─static 静态资源目录
│ │ └─avatarUrl.png 默认用户头像图片资源
│ ├─changelog.md 更新日志
│ ├─package.json 包管理文件
│ └─readme.md 插件自述文件
uni-im v1.0.0 暂时比较简单,云端有1个云对象`uni-im-co`,2个opendb数据表(会话表`uni-im-conversation`,聊天消息表`uni-im-msg`)
名词解释
- 聊天会话ID
根据通讯双方用户id,生成的唯一索引值;
- 聊天会话
以会话ID为索引的一组数据,记录:未读消息数量、会话更新时间、会话类型、会话所属用户的id、对话的用户id、对话的群id、最后一条消息概述(文本消息的前15个字,消息为多媒体时只描述类型)
## uni-im-co 云函数(云对象)
### API列表
|API |描述 |
|-- |-- |
|loginWithJWT |基于jwt签名的账号登录方式[见下方](#uniImCoLoginWithJWT) |
|getConversationList|获取会话列表[见下方](#coGetConversationList) |
|sendMsg |发送聊天消息[见下方](#coSendMsg) |
#### 账号登录loginWithJWT@uniImCoLoginWithJWT
如果你的项目是基于非uniCloud开发的项目(比如:应用服务端的开发语言是php、java等,用户信息并没未存储在uniCloud云数据库中)需要通过跨平台签名认证的方式,向uniCloud账户体系新增用户(创建过则更新用户信息)并获取token实现登录。
前置要求:添加`uni-im`配置文件,打开:`/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/`;新建`uni-im`文件夹和`config.json`文件,示例如下:
```json
{
"jwtSecret":"jwtSecretDemo",
}
```
这里的值`jwtSecretDemo`为示例,注意修改为自己的,使用一个较长的字符串即可(越长安全性越高,建议大于32位)。
**接口形式**
```js
await uniImCo.loginWithJWT(signedData)
```
signedData 为通过jwt签名后的数据
> 各类计算机语言,jwt库下载地址:https://jwt.io/libraries
**signedData 包含的数据说明**
| 字段 | 类型 |必填 | 描述 |
| -- | -- | -- | -- |
| exp | timestamp | 否 | 签名数据的过期时间 |
| userInfo | Object | 是 | 用户信息[详情](#signedDataUserInfo) |
**userInfo 参数说明 @signedDataUserInfo**
| 字段 | 类型 |必填| 描述 |
| -- | -- | --| -- |
| openid | String| 是 | 原系统的用户id |
| nickname | String| 否 | 用户昵称 |
| avatar_file | file | 否 | 用户头像文件对象 |
| gender | int | 否 | 用户性别:0 未知 1 男性 2 女性 |
| mobile | String| 否 | 手机号码 |
| email | String| 否 | 邮箱地址 |
| role | Array | 否 | 用户角色列表,由role_id组成的数组[详情查看](https://uniapp.dcloud.net.cn/uniCloud/uni-id-summary.html#rbac)。