> 本插件需要HBuilderX 3.6.9 及其以上版本支持。 ![](https://web-assets.dcloud.net.cn/ext/uni-im/ext-im.png) # 简介 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),完善的账户体系 - 支持服务端为非uniCloud(比如:应用服务端的开发语言是php、java、go、.net、python、c#等)或 不基于uni-id-pages 开发的项目接入 案例: 如图:在插件市场任意插件详情页面,点击咨询作者按钮,即可看到基于uni-im搭建的客服系统。 下载地址:[https://ext.dcloud.net.cn/plugin?name=uni-im](https://ext.dcloud.net.cn/plugin?name=uni-im) ## 特点优势 - 性价比高;前后端代码均免费开源,相比竞品使用uni-im仅需花费极少的托管在uniCloud(serverless服务器)产生的费用[详情查看](#cost) - 全端可用 - App端支持nvue,更好的长列表性能。list组件性能优势[详情参考](https://uniapp.dcloud.net.cn/component/list.html) - 智能本地缓存,更快的历史消息加载速度,更小的网络请求压力 - 中心化响应式数据管理,切换会话不重头加载数据,更流畅的体验 - App端聚合多个手机厂商推送通道,app不在线也可以收到消息 ## 版本计划 ### 已上线 - 应用内嵌入uni-im,使用户方便、实时的与App运营者互动,咨询问题、反馈意见、进行投诉。 - 可发送文字、图片、音频、视频、代码、任意文件 - im交友场景:群聊、好友关系 ### 后续计划 1. 通信方式扩展:音频通话、视频通话 2. 细节完善:聊天记录识别电话邮件、消息删除和批删、消息回复、消息转发和批转、消息撤回、勿扰设置、会话置顶、留言转文字、图片提取文字 3. 客服场景:管理端支持座席 优先开发哪些,取决于开发者的反馈。同时也欢迎开发者共建这个开源项目。 > uni-im相关功能建议或问题,可以加入由uni-im(本插件)搭建的交流群,[点此加入](https://im.dcloud.net.cn/#/?joinUniImGroup=1),备用QQ群(当系统处于维护中使用)群号:[854520009](https://qm.qq.com/cgi-bin/qm/qr?k=DJNSajXAYHnYcr9pouOfxF9Rwwl1AJHc&jump_from=webapi&authKey=HZ1fG58Eudp3o0GCoyx1/UPMY9Fv1sGT5jdqYqPJlTGT0XVUip3Bk8E+UyToQOMo) ## 使用uniCloud产生的费用说明@cost uni-im本身并不收费,实际使用中需要依赖uniCloud云服务,会产生费用;而uniCloud的价格很实惠: - 调用10000次云函数仅需0.0133元 - 调用10000次数据库查询仅需0.015元 > 更多计费参考:[阿里云版uniCloud按量计费文档](https://uniapp.dcloud.net.cn/uniCloud/price.html#aliyun-postpay) ### 举例说明: - 单聊场景,向用户发送一条消息的过程: 1. 调用uni-im-co云对象的sendMsg方法(产生1次云函数请求) 2. 查询当前对话的会话记录(产生1次云数据库读操作) 3. 根据步骤2的查询结果,如果已经有会话记录,就更新会话,否则就创建一条会话记录(产生1次云数据库写操作) 4. 查询发送消息的用户信息,用于接收消息时在通知栏显示发送者昵称和头像(产生1次云数据库读操作) 5. 记录发送的消息内容到数据库,用于保存消息历史记录(产生1次云数据库写操作) 6. 以`user_id`为标识通过`uni-push2`向用户发送消息会产生0.00000283元uniCloud使用费用[详情查看](https://uniapp.dcloud.net.cn/unipush-v2.html#cost) 合计:1次云函数请求、2次数据库读操作、2次数据库写操作、1次uni-push2推送操作,即 (1 * 0.0133 + 2 * 0.015 + 2 * 0.05 + 1 * 0.0283)/10000 ≈ 0.000017元 - 群聊场景,向用户发送一条消息的过程: 1. 调用uni-im-co云对象的sendMsg方法(产生1次云函数请求) 2. 查询当前用户是否为群成员,防止非群成员发送消息(产生1次云数据库读操作) 3. 查询当前对话的会话记录(产生1次云数据库读操作) 4. 根据步骤3的查询结果,如果已经有会话记录,就更新会话,否则就创建一条会话记录(产生1次云数据库写操作) 5. 查询发送消息的用户信息,用于接收消息时在通知栏显示发送者昵称和头像(产生1次云数据库读操作) 6. 记录发送的消息内容到数据库,用于保存消息历史记录(产生1次云数据库写操作) 7. 以群id为参数,调用uni-im-co云对象的sendMsgToGroup方法,这是一个递归方法每次向500名群成员推送消息(如果群成员数量为0-500只需执行1次,500-1000需执行2次,以此类推),(会产生最少1次数据库读操作,和1次以`user_id`为标识通过`uni-push2`向用户发送消息会产生0.00000283元uniCloud使用费用[详情查看](https://uniapp.dcloud.net.cn/unipush-v2.html#cost)) 合计:向500人群发送消息,会产生:1次云函数请求、4次数据库读操作、2次数据库写操作、1次uni-push2推送操作,即 (1 * 0.0133 + 4 * 0.015 + 2 * 0.05 + 1 * 0.0283)/10000 ≈ 0.000020元 相比市面上同类型产品,使用uni-im仅需花费如此便宜的uniCloud(serverless服务器)费用;在价格这块uni-im性价比极高。 # 快速部署体验 ## 前提条件 1. 开通uniCloud并创建服务空间 [控制面板](https://unicloud.dcloud.net.cn/) 传统的IM产品服务端代码托管在服务商名下的服务器内,你只拥有代码和产生的数据的使用权,并非所有权;而uni-im的前后端代码都是开源的,是将代码托管在你名下的unicloud([serverless](https://uniapp.dcloud.net.cn/uniCloud/#%E4%BB%80%E4%B9%88%E6%98%AFserverless)服务器)内。 2. 开通`uni-push2.0`(注意:**无论是APP、小程序、web端都需要开通,否则消息将无法实时更新**)[详情参考](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. 对项目根目录uniCloud点右键选择“云服务空间初始化向导”界面按提示部署项目(注意:选择绑定的服务空间,须在uni-push2.0的[web控制台](https://dev.dcloud.net.cn/pages/app/push2/info)关联) 4. 在HBuilderX控制台,更改`连接本地云函数`为`连接云端云函数` 5. `运行项目`到2个不同的浏览器,因为在同一个浏览器打开相同网络地址(ip或者域名)的uni-im项目,socket会相互占线。 所以需要使用两个浏览器(或者使用浏览器`打开新的无痕式窗口`功能充当第二个浏览器)分别`注册账号并登录`, 到此部署已经结束 6. 向对应的用户发起会话,通过访问路径:`/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. 部署到uniCloud 对项目根目录uniCloud点右键,选择“云服务空间初始化向导” 按提示部署项目(注意:选择绑定的服务空间,须在uni-push2.0的[web控制台](https://dev.dcloud.net.cn/pages/app/push2/info)关联) 6. 登录uni-im uni-im的服务端代码托管在uniCloud下,账户体系是[uni-id](https://uniapp.dcloud.net.cn/uniCloud/uni-id-summary.html)的; uni-app生态下绝大部分项目的架构与uni-im相同,所以不需要考虑账号打通问题,用户登录项目后,不需要额外登录uni-im。 而有些传统项目,服务端的开发语言是php、java、go、.net、python、c#等,是自己设计的账号体系;用户登录所获得的token,与uni-im所需的token不是同一个账号体系;需要在传统服务器端,通过[uni-id的外部系统联登](https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#external)同步你项目的账号数据到uni-im用户体系并获得uni-id的token,客户端再调用uniImUtils的login方法登录uni-im;示例代码如下: ```js import uniImUtils from '@/uni_modules/uni-im/common/utils.js'; uni.request({ url: 'https://www.example.com/login', //仅为示例,并非真实接口地址。 data: { username: 'test', password: '123456' }, success:async (res) => { console.log(res.data); // 得到你自己项目的token和uni-id的token // uniImToken 是一个对象:{token,tokenExpired} let {token,uniImToken} = res.data uni.setStorageSync('token',token) await uniImUtils.login(uniImToken) } }); ``` 其他情况: - 客户端如果不是uni-app的,如果是网页,可iframe内嵌。如果是原生app,可嵌入[uni小程序sdk](https://nativesupport.dcloud.net.cn/README) - 不基于`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() ``` 7. 确保账户对接成功后,打开“用户列表页”,路径:`/uni_modules/uni-im/pages/userList/userList`可以看到所有的注册用户 8. 点击某个用户,会自动创建与该用户的会话,并打开“聊天对话页”(路径:`/uni_modules/uni-im/pages/chat/chat`),然后就可以开始聊天了。 9. 还可以导入uni-im的示例项目作为管理员端与用户聊天。 10. 如果你是2个不同appId的应用相互通讯(比如:淘宝的买家端和卖家端通讯)的场景,请打开聊天对话文件(路径:`/uni_modules/uni-im/pages/chat/chat`)搜索`data.appId = this.systemInfo.appId`修改`this.systemInfo.appId`为相对的appId 不基于uni-id-pages开发的项目还要注意以下两个问题: 1. 退出登录;需要在执行退出登录/切换账号时,调用uni-id的退出登录接口。否则会出现退出登录后的设备仍然能收到im消息,或导致此设备再登录其他账号不能正常收到消息的问题;示例代码如下: ```js import {mutations as uniIdMutations} from '@/uni_modules/uni-id-pages/common/store.js' uniIdMutations.logout() ``` 2. token有效期问题,保证你的项目token有效期和uni-id的token有效期保持一致。这涉及两个操作: - 配置uni-id的token过期时间与你的项目token有效期一致。配置路径:`/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json`,关于配置说明[详情查看](https://uniapp.dcloud.net.cn/uniCloud/uni-id-summary.html#config) - 如果你的项目有token续期逻辑,需要在续期后调用uni-id的token续期接口,示例代码: ```js const uniIdCo = uniCloud.importObject("uni-id-co", {customUI: true}) await uniIdCo.refreshToken() ``` ## 限制普通用户向其他用户发起会话 客服场景下,我们希望管理员客服可以向任意用户发起会话。而普通用户的会话对象只能是客服。 - 客户端限制 删除或隐藏“用户列表页”和“会话列表页”,仅保留“聊天对话页”。并绘制按钮,如:“联系客服”,点击后打开“聊天对话页” 逻辑代码如下: ```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(已过期,请使用[uni-id的外部系统联登](https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#external)) |基于jwt签名的账号登录方式[见下方](#uniImCoLoginWithJWT)| |getConversationList |获取会话列表[见下方](#coGetConversationList) | |sendMsg |发送聊天消息[见下方](#coSendMsg) | #### 账号登录loginWithJWT@uniImCoLoginWithJWT 此登录方式已经过期,仅为旧项目保留。新项目请使用[uni-id的外部系统联登](https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#external) 如果你的项目是基于非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)。
当值为:`["admin"]`表示为超级管理员,不受任何权限限制;| 签名密钥配置路径: `/cloudfunctions/common/uni-config-center/uni-im/config.json` **Nodejs环境,生成signedData示例代码:** ```js const jwtSecret = "jwtSecretDemo"; //切勿泄露此密钥,且应当与uni-config-center中配置的一致 const jwt = require("jsonwebtoken"); const payload = { "exp":Date.now() + 60 * 1000,//60秒后过期 "userInfo":{ "avatar_file":{ "extname": "", "name": "", "url":'https://web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png' }, "openid":"100001", "nickname":"张三", "role":["admin"] // 设置该用户为超级管理员,不受任何权限限制 } } // 签名 let token = jwt.sign(payload, jwtSecret); console.log(token); /* // 验证签名 try{ let decoded = jwt.verify(token, jwtSecret); console.log(decoded) }catch{ console.error("签名验证失败") } */ ``` **返回值** |参数名 |类型 |说明 | |-- |-- |-- | |errCode |string|number |错误码 | |errMsg |string |错误信息 | |newToken |object |新token信息(uniCloud客户端监听到云对象返回newToken,
会自动将新token及过期时间存储在storage内。
当客户端调用云函数(云对象)的方法时,会自动带上token供服务端校验 | | |- token |string |token | | |- tokenExpired|string |token过期时间 | **示例代码:** 以下为客户端的示例,演示了在客户端中登录之前的账户体系成功后,把signedData传给uni-im,调用uni-im的联登接口。 ```js // 1. 导入uniCloud客户端账户体系,用户信息状态管理模块 import { mutations as uniIdMutations } from '@/uni_modules/uni-id-pages/common/store.js'; // 2. 导入uni-im的云对象 const uniImCo = uniCloud.importObject("uni-im-co") // 3. 客户端向传统服务器的登录接口发起请求,验证登录信息无误后:将userInfo通过jwt签名与token一起返回 uni.request({ data:{ username:"xxx", password:"xxx" }, url:'https://xxx.com/login.php',//你在传统服务端的登录地址(示例链接非真实地址) success: async res => { const {token,signedData} = res.data //4. 存储token实现登录 uni.setStorageSync('token',token) //5. 将签名后的signedData作为参数调用uni-im的登录接口 res = await uniImCo.loginWithJWT(signedData) if(res.errCode){ return uni.showModal({ content: JSON.stringify(), showCancel: false, confirmText: '知道了', }); } //6. 更新uniId store内的当前用户信息(uni-im显示当前用户头像、昵称时会用到) await uniIdMutations.updateUserInfo() /* // 注:uni-im会话列表页面,已内置步骤5、6;如果是登录后,需要立即打开会话页面的项目,直接将signedData作为token传参,可省略步骤5、6。如下: uni.navigateTo({ url:'/uni_modules/uni-im/pages/index/index?token='+signedData, complete: () => { uni.hideLoading() } }) */ } }) ``` **注意:** 登录有效期默认为:2小时;当有效期小于1小时,账号活跃会自动续期。如果与你的系统登录配置不同请修改。配置路径:`uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json`,配置文档[详情查看](https://uniapp.dcloud.net.cn/uniCloud/uni-id-summary.html#config) #### 获取会话列表getConversationList@coGetConversationList **参数说明** |参数名 |类型 |必填 |说明 | |-- |-- |-- |-- | |limit |number |否 |数量,默认值:500 | |page |number |是 |页码 | **返回值** |参数名 |类型 |说明 | |-- |-- |-- | |errCode|string|number |错误码,0表示成功 | |errMsg |string |错误信息 | |data |array |会话数据 | #### 发送聊天消息sendMsg@coSendMsg |参数名 |类型 |必填 |说明 | |-- |-- |-- |-- | |to_uid |string |否 |接受消息的用户id | |appId |string |是 |接收消息的appId;如果你是2个不同appId的应用相互发,请修改此值为相对的appId | |type |string |是 |消息类型,暂时仅支持:text(表示文本类型)、image(表示图片类型)| |body |string |是 |消息内容,`type = text`时为文本内容.`type = image`时为图片网络地址| **返回值** |参数名 |类型 |说明 | |-- |-- |-- | |errCode |string|number |错误码,0表示成功 | |errMsg |string |错误信息 | |data |object | | | |- create_time |无 |创建时间 | **接口形式** ```js const uniImCo = uniCloud.importObject('uni-im-co', { customUI: true }); await uniImCo.sendMsg({ to_uid:"630cacf46293d20001f3c368", type:"text", body:"您好!" }) ``` ## 服务端配置@uni-im-cloud-config 路径:`/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-im/config.json` |字段名 |数据类型 |说明 | |-- |-- |-- | |jwtSecret |string |WJT联登录密钥 | |admin_uid |string/boolean |客服用户id,不限制则填`false`即可;仅conversation_grade的值为100时有效 | |conversation_grade |int |控制发起会话的条件,详情[会话控制](#conversation_grade)| ### 会话控制@conversation_grade |值 |说明 | |-- |-- | |0 |不限制 | |100|仅限当前用户向:客服、好友、群成员发起会话 | |200|仅限当前用户向:好友或群成员发起会话 | ## 客户端sdk@clientSkd ### Vuex状态管理 uni-im的数据通过Vuex进行状态管理,如果你不了解Vuex[详情参考](https://v3.vuex.vuejs.org/zh/)。 这种中心化响应式的数据管理,在用户切换聊天会话时,数据不会不重头加载;降低获取数据的网络请求次数,提高了效率,带来更好的用户体验。 文件路径:`/uni_modules/uni-im/common/store.js` #### state |名称 |类型 |说明 | |-- |-- |-- | |conversationDatas |object |由多个[会话对象](#conversation)组成,以会话id为key | |currentConversationId |string |正在对话的会话id | |heartbeat |timestamp |心跳(精确到秒) | 概念说明: ##### 心跳 heartbeat uni-im的会话列表和消息列表,需要显示实时的发生时间。而一个应用开启太多的定时器,会消耗大量的系统性能。 所以uni-im提供了一个响应式数据`heartbeat`,挂载在Vuex,由uniImInit方法:用一个定时器刷新。 ##### 会话对象 conversation@conversation |属性名 |类型 |说明 | |-- |-- |-- | |id |string |当前会话id | |title |string |普通会话为对方的用户名或昵称、群会话为群昵称 | |avatar_file |uniCloud file |普通会话为对方的用户头像、群会话为群头像 | |owner_uid |string |所属用户id | |unread_count |number |未读消息数 | |user_id |string |对话的用户id(群聊会话时为空) | |group_id |string |对话的群聊id(普通会话时为空) | |update_time |timestamp |更新时间(每次会话会更新) | |msgList |array |当前会话聊天数据列表 | |chatText |string |当前会话的文本框文字内容 | #### getters |名称 |参数 |类型 |说明 | |-- |-- |-- |-- | |conversationList |无 |array |排序后的会话对象数据列表,与conversationDatas为映射关系| |conversation |会话id |object |传入会话id获取会话 | |unread_count |无 |string |当前应用总未读消息数 | #### mutations |方法名 |参数 |说明 | |-- |-- |-- | |setCurrentConversationId |会话id |设置全局变量 正在聊天的用户的会话id| |mergeConversationDatas |会话数据 |合并(新增/覆盖)会话数据到列表 | |updateConversation |[id, data, cover]依次为:会话id,会话数据,是否覆盖 |更新会话 | |updateTimestamp |无 |更新心跳时间戳 | #### actions |方法名 |参数 |说明 | |-- |-- |-- | |clearUnreadCount |无 |清空当前会话未读消息数 | |loadMoreConversation |可选参数`conversation_id`,用于指定要加载的会话id |加载更多会话数据 | |setMsgList |详见[setMsgList 说明](#setMsgListParam) |设置消息列表 | **setMsgList 说明**@setMsgListParam |参数名 |类型 |是否必填 |说明 | |-- |-- |-- |-- | |conversation_id|string |是 |会话id | |action |string |否 |操作类型,默认值为`set`,详见[action说明](#setMsgListActionParam) | |data |object、array |是 |聊天数据 。更新或插入数据时,data为单条消息内容,类型:object。设置聊天列表数据时,为多条消息集合,类型:array。| |id |string |`action = update`时必填 |要更新的消息id | |save |boolean |否 |是否保存到storage,默认值为`false` | **action 说明** @setMsgListActionParam |参数名 |说明 | |-- |-- | |set |设置聊天列表数据 | |push |向后插入数据 | |unshift|向前插入数据 | |update |更新某一条聊天数据 | ### 聊天消息管理类库 为了提高聊天数据的获取速度,`uni-im`将历史消息存储在本地的storage中。 因此,聊天数据由:云端数库中的数据和本地storage数据两部分组成。 而何时应当从网络拉取数据,何时从本地获取数据是一个复杂的逻辑。uni-im将它封装成一个im消息数据操作类。 使用示例: ```js import MsgManager from '@/uni_modules/uni-im/common/msgManager.js'; const currentConversation = this.$store.uniIm.getters.conversation('当前会话id') const msg = new MsgManager(currentConversation); //拉取更多数据 let data = await this.msg.getMore(); ``` |属性名 |类型 |说明 | |-- |-- |-- | |isInit |boolean |是否已经加载过首页数据 | |getMore |function |获取更多历史聊天数据(如果数据来源服务端,会自动保存到storage) | |pageLimit |number |配置的聊天数据分页值 | ### storage操作库 uni-app的[数据缓存](https://uniapp.dcloud.net.cn/api/storage/storage.html#),是通过不同的key来存储和获取数据。 如下示例: ```js // 设置数据 uni.setStorageSync('storage_key', 'hello'); // 读取数据 uni.getStorageSync('storage_key'); ``` 以不同的key值,单独存储一组数据; 而im聊天数据可能非常庞大,需要分页存储,且支持按时间和页码检索。 uni-im-storage应需而生,封装了这些方法: |方法名 |说明 | |-- |-- | |update |更新数据 [详见](#update) | |getData|获取数据 [详见](#getData) | |append |向某个会话的聊天数据中添加一条聊天数据(一般用于收到) | |insert |向前插入数据 | uni-im-storage 还有一个可以配置的属性值`pageLimit`即:加载历史聊天数据时每一页的数据。 配置方式,修改路径`/uni_modules/uni-im/common/uni-im-storage.js`第二行pageLimit的值(默认值:`30`)。 **update 参数说明**@updateMsgStorage |参数名 |类型 |是否必填 |说明 | |-- |-- |-- |-- | |id |string |是 |消息id | |data |object |是 |消息数据 | **getData 参数说明**@getData |参数名 |类型 |是否必填 |说明 | |-- |-- |-- |-- | |conversation_id|string |是 |会话id | |limit |object |否 |获取的条数,默认为配置的pageLimit的值 | |page |object |page、maxTime、miniTime 三选一 |页码。支持负数,如:-1表示倒数第一页 | |maxTime |object |page、maxTime、miniTime 三选一 |获取的消息的最大时间 | |miniTime |object |page、maxTime、miniTime 三选一 |暂不支持 | #### 工具类库@utils utils封装了uni-im常用方法的模块,路径:`/uni_modules/uni-im/common/utils.js` |名称 |类型 |说明 |入参 |返回值 | |-- |-- |-- |-- |-- | |init |function |初始化uni-im(监听聊天消息,定时每秒更新心跳值为当前时间戳)|无 |无 | |getConversationId |function |获取会话id |与你对话的用户id或群id |无 | |formatTime |function |时间戳转化为格式化 |时间戳:timestamp |格式化后的时间字符串。如:x年x月x日,昨天,下午,1小时前等 | ## 项目升级 uni-im遵循uni-app的插件模块化规范,即:[uni_modules](https://uniapp.dcloud.io/uni_modules)。 在项目根目录下的`uni_modules`目录下,以插件ID即`uni-im`为插件文件夹命名,在该目录右键也会看到“从插件市场更新”选项,点击即可更新该插件。也可以用插件市场web界面下载覆盖。 ### 升级旧项目为 uni-im 1.4.0(群聊版) 注意事项 此版本更新了`uni-im-conversation`表的 `user_id` 字段名为 `friend_uid` && `owner_uid` 字段名为 `user_id`。 旧版uni-im,需通过:`uniCloud/database/JQL查询.jql` 执行以下jql语句,修改字段名 1. 先执行: ```js db.collection('uni-im-conversation').update({ "user_id": db.command.rename('friend_uid') }) ``` 2. 再执行:(**注意:不要两句一起执行,也别弄反顺序**) ```js db.collection('uni-im-conversation').update({ owner_uid: db.command.rename('user_id') }) ``` >此版本新增`会话控制`配置,[详情查看](#conversation_grade) ## 许可协议 uni-im源码使用许可协议 2022年10月 本许可协议,是数字天堂(北京)网络技术有限公司(以下简称DCloud)对其所拥有著作权的“DCloud uni-im”(以下简称软件),提供的使用许可协议。 您对“软件”的复制、使用、修改及分发受本许可协议的条款的约束,如您不接受本协议,则不能使用、复制、修改本软件。 授权许可范围 a) 授予您永久性的、全球性的、免费的、非独占的、不可撤销的本软件的源码使用许可,您可以使用这些源码制作自己的应用。 b) 您只能在DCloud产品体系内使用本软件及其源码。您不能将源码修改后运行在DCloud产品体系之外的环境,比如客户端脱离uni-app,或服务端脱离uniCloud。 c) DCloud未向您授权商标使用许可。您在根据本软件源码制作自己的应用时,需以自己的名义发布软件,而不是以DCloud名义发布。 d) 本协议不构成代理关系。 DCloud的责任限制 “软件”在提供时不带任何明示或默示的担保。在任何情况下,DCloud不对任何人因使用“软件”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。 您的责任限制 a) 您需要在授权许可范围内使用软件。 b) 您在分发自己的应用时,不得侵犯DCloud商标和名誉权利。 c) 您不得进行破解、反编译、套壳等侵害DCloud知识产权的行为。您不得利用DCloud系统漏洞谋利或侵害DCloud利益,如您发现DCloud系统漏洞应第一时间通知DCloud。您不得进行攻击DCloud的服务器、网络等妨碍DCloud运营的行为。您不得利用DCloud的产品进行与DCloud争夺开发者的行为。 d) 如您违反本许可协议,需承担因此给DCloud造成的损失。 本协议签订地点为中华人民共和国北京市海淀区。 根据发展,DCloud可能会对本协议进行修改。修改时,DCloud会在产品或者网页中显著的位置发布相关信息以便及时通知到用户。如果您选择继续使用本框架,即表示您同意接受这些修改。 条款结束