From 06b0cf7326fb5bf98d736dff0d476bc0baa20e6b Mon Sep 17 00:00:00 2001 From: DCloud_JSON Date: Fri, 14 Apr 2023 22:05:06 +0800 Subject: [PATCH] Update uni-im.md --- docs/uniCloud/uni-im.md | 779 +++++++++++++++++++--------------------- 1 file changed, 377 insertions(+), 402 deletions(-) diff --git a/docs/uniCloud/uni-im.md b/docs/uniCloud/uni-im.md index 4effee716..aa30c4e21 100644 --- a/docs/uniCloud/uni-im.md +++ b/docs/uniCloud/uni-im.md @@ -1,6 +1,5 @@ -> 本插件需要HBuilderX 3.6.9 及其以上版本支持。 +> 本文为uni-im v2.x 的文档,如果旧项目需要继续使用老版本的uni-im v1.x,另见:[https://gitcode.net/dcloud/hello-uni-im/-/blob/main/README.md](https://gitcode.net/dcloud/hello-uni-im/-/blob/main/README.md) -![](https://web-assets.dcloud.net.cn/ext/uni-im/ext-im.png) # 简介 uni-im是云端一体的、全平台的、免费的、开源即时通讯系统。 - 基于uni-app,App、小程序、web全端兼容 @@ -21,8 +20,8 @@ uni-im是云端一体的、全平台的、免费的、开源即时通讯系统 - 性价比高;前后端代码均免费开源,相比竞品使用uni-im仅需花费极少的托管在uniCloud(serverless服务器)产生的费用[详情查看](#cost) - 全端可用 - App端支持nvue,更好的长列表性能。list组件性能优势[详情参考](https://uniapp.dcloud.net.cn/component/list.html) -- 智能本地缓存,更快的历史消息加载速度,更小的网络请求压力 -- 中心化响应式数据管理,切换会话不重头加载数据,更流畅的体验 +- 智能本地缓存(app端sqlite,web端indexDB,小程序端storage),更快的历史消息加载速度,更小的网络请求压力 +- 中心化响应式数据管理,切换会话无需重新加载数据,更流畅的体验 - App端聚合多个手机厂商推送通道,app不在线也可以收到消息 ## 版本计划 @@ -30,18 +29,17 @@ uni-im是云端一体的、全平台的、免费的、开源即时通讯系统 - 应用内嵌入uni-im,使用户方便、实时的与App运营者互动,咨询问题、反馈意见、进行投诉。 - 可发送文字、图片、音频、视频、代码、任意文件 - im交友场景:群聊、好友关系 +- 会话细节:消息删除、撤回、消息回复 ### 后续计划 1. 通信方式扩展:音频通话、视频通话 -2. 细节完善:聊天记录识别电话邮件、消息删除和批删、消息回复、消息转发和批转、消息撤回、勿扰设置、会话置顶、留言转文字、图片提取文字 -3. 客服场景:管理端支持座席 +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) -如何将chatGPT接入uni-im,参考文章:[https://ask.dcloud.net.cn/article/40314](https://ask.dcloud.net.cn/article/40314) - ## 使用uniCloud产生的费用说明@cost uni-im本身并不收费,实际使用中需要依赖uniCloud云服务,会产生费用;而uniCloud的价格很实惠: @@ -86,6 +84,7 @@ uni-im本身并不收费,实际使用中需要依赖uniCloud云服务,会产 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会相互占线。 所以需要使用两个浏览器(或者使用浏览器`打开新的无痕式窗口`功能充当第二个浏览器)分别`注册账号并登录`, 到此部署已经结束 @@ -121,67 +120,12 @@ uni-im本身并不收费,实际使用中需要依赖uniCloud云服务,会产 ``` -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 +4. 部署到uniCloud 对项目根目录uniCloud点右键,选择“云服务空间初始化向导” 按提示部署项目(注意:选择绑定的服务空间,须在uni-push2.0的[web控制台](https://dev.dcloud.net.cn/pages/app/push2/info)关联) -6. 登录uni-im +5. 登录uni-im - uni-im的服务端代码托管在uniCloud下,账户体系是[uni-id](https://uniapp.dcloud.net.cn/uniCloud/uni-id-summary.html)的; + uni-im的服务端代码托管在uniCloud下,账户体系是[uni-id 4.0+](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;示例代码如下: @@ -198,9 +142,9 @@ uni-im本身并不收费,实际使用中需要依赖uniCloud云服务,会产 success:async (res) => { console.log(res.data); // 得到你自己项目的token和uni-id的token - // uniIdToken 是一个对象:{token,tokenExpired} let {token,uniIdToken} = res.data uni.setStorageSync('token',token) + // 【请注意】这里的`uniIdToken` 是一个`对象`:包含:`token`和`tokenExpired` await uniImUtils.login(uniIdToken) } }); @@ -244,10 +188,10 @@ uni-im本身并不收费,实际使用中需要依赖uniCloud云服务,会产 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 +6. 确保账户对接成功后,打开“用户列表页”,路径:`/uni_modules/uni-im/pages/userList/userList`可以看到所有的注册用户 +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开发的项目还要注意以下两个问题: 1. 退出登录;需要在执行退出登录/切换账号时,调用uni-id的退出登录接口。否则会出现退出登录后的设备仍然能收到im消息,或导致此设备再登录其他账号不能正常收到消息的问题;示例代码如下: @@ -263,6 +207,13 @@ const uniIdCo = uniCloud.importObject("uni-id-co", {customUI: true}) await uniIdCo.refreshToken() ``` +常见问题: +1. 为什么不能实时接收到推送的消息,需要刷新或者关闭重新打开才能收到? +答: uni-im通过`uni-push2`实现消息实时送达,请检查是否已正确配合并开通,且在配置正常后重新登录 + +2. 怎么样快速上手 +答:先下载示例项目,部署并正确配置push后,体验没问题了再部署到自己的项目。 + ## 限制普通用户向其他用户发起会话 客服场景下,我们希望管理员客服可以向任意用户发起会话。而普通用户的会话对象只能是客服。 @@ -280,232 +231,197 @@ uni.navigateTo({ 1. 添加`uni-im`配置文件,打开:`/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/`;新建`uni-im`文件夹和`config.json`文件,示例如下: ```json { - "admin_uid":false + "customer_service_uids":["user-id-01","user-id-02"] } ``` -2. 配置`admin_uid`的值为管理员客服的user_id(支持多个以数组的形式指定),如果会话双方均不属于此域则无法通讯。不配置或为false则表示不限制。 +2. 配置`customer_service_uids`的值为管理员客服的user_id(支持多个以数组的形式指定),如果会话双方均不属于此域则无法通讯。不配置或为false则表示不限制。 # 开发文档 ## 目录结构
 
-├─uni_modules                                         存放[uni_module](/uni_modules)规范的插件。
+├─uni_modules
 │    ├─其他module
 │    └─uni-im
 │        ├─uniCloud
-│        │    ├─cloudfunctions                        云函数目录
-│        │    │    └─uni-im-co                        集成调用uni-im方法的云对象
+│        │    ├─cloudfunctions                         云函数目录
+│        │    │    └─uni-im-co                         集成调用uni-im方法的云对象
 │        │    └─database
-│        │    	├─uni-im-conversation.schema.json     聊天会话表的表结构
-│        │    	└─uni-im-msg.schema.json              聊天消息表的表结构
+│        │      ├─uni-id-users.schema.ext.js           用户表触发器
+│        │      ├─uni-im-conversation.schema.ext.js    聊天会话表触发器
+│        │      ├─uni-im-conversation.schema.json      聊天会话表的表结构
+│        │      ├─uni-im-friend-invite.schema.ext.js   邀请加为好友表触发器
+│        │      ├─uni-im-friend-invite.schema.json     邀请加为好友表表结构
+│        │      ├─uni-im-friend.schema.ext.js          好友关系表触发器
+│        │      ├─uni-im-friend.schema.json            好友关系表表结构
+│        │      ├─uni-im-group-join.schema.ext.js      申请加入群聊表触发器
+│        │      ├─uni-im-group-join.schema.json        申请加入群聊表表结构
+│        │      ├─uni-im-group-member.schema.ext.js    群成员表触发器
+│        │      ├─uni-im-group-member.schema.json      群成员表表结构
+│        │      ├─uni-im-group.schema.ext.js           群信息表触发器
+│        │      ├─uni-im-group.schema.json             群信息表表结构
+│        │      ├─uni-im-msg.schema.ext.js             聊天消息表触发器
+│        │      ├─uni-im-msg.schema.json               聊天消息表表结构
+│        │      └─uni-im-notification.schema.json      推送消息记录表(仅记录系统消息)
 │        ├─common
-│        │    ├─msgManager.js                         消息管理类库
-│        │    ├─store.js                              状态管理
-│        │    ├─utils.js                              工具类库
-│        │    └─uni-im-storage.js                     封装storage操作库
+│        │    ├─appEvent.js             生命周期事件api库
+│        │    ├─emojiCodes.js           emoji表情列表
+│        │    ├─initIndexDB.js          indexDB本地数据库初始化文件(仅Web端使用)
+│        │    ├─md5.js                  md5哈希加密算法(用于本地直接生成会话id)
+│        │    ├─toFriendlyTime.js       时间戳转友好时间提示字符库文件(如:x年x月x日,昨天,下午,周二,1小时前等)
+│        │    ├─sqlite.js               sqlite本地数据库初始化文件(仅App端使用)
+│        │    └─utils.js                工具类库
 │        ├─components
-│        │    └─uni-im-msg                            显示聊天消息气泡组件
+│        │    └─uni-im-msg              显示聊天消息气泡组件
+│        ├─ lib
+│        │    ├─createObservable.js     创建响应式对象文件
+│        │    ├─main.js                 核心库入口文件
+│        │    └─msgManager.js           消息管理类库
 │        ├─pages
 │        │    ├─chat
-│        │    │    └─chat.nvue                        聊天对话页
-│        │    ├─index                    
-│        │    │     └─index.nvue                      会话列表页
-│        │    └─userList                    
-│        │         └─userList.vue                     用户列表页
-│        ├─static                                     静态资源目录
-│        │    └─avatarUrl.png                         默认用户头像图片资源
-│        ├─changelog.md                               更新日志
-│        ├─package.json                               包管理文件
-│        └─readme.md                                  插件自述文件
+│        │    │    ├─info.nvue           对话详情(显示好友信息,可在此页面操作删除好友。后续支持:备注好友、打标签、拉黑、屏蔽等功能)
+│        │    │    └─chat.nvue           聊天对话页
+│        │    ├─common                   公共页面
+│        │    │    ├─uni-im-code-pages   代码类型消息浏览专用页面
+│        │    │    └─video               视频播放专用页面
+│        │    ├─contacts
+│        │    │    ├─addPeopleGroups     查找并添加用户或群
+│        │    │    ├─createGroup         创建群聊
+│        │    │    ├─groupList           我的群列表
+│        │    │    ├─notification        im系统通知页面
+│        │    │    └─contacts.nvue       联系人页面
+│        │    ├─group                    
+│        │    │    ├─groupQRCode         群二维码页面(未完成)
+│        │    │    └─info                群信息页面(管理群)
+│        │    ├─index                    首页(展示会话列表)
+│        │    └─userList                 所有用户列表页
+│        ├─static                        静态资源目录
+│        ├─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、对话的用户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) | +以会话ID为索引的一组数据,记录:未读消息数量、会话更新时间、会话类型、会话所属用户的id、对话的用户id、对话的群id、群信息、最后一条消息概述(文本消息的前15个字,消息为多媒体时只描述类型) -#### 账号登录loginWithJWT@uniImCoLoginWithJWT +## uni-im-co 云函数(云对象) +API列表 -此登录方式已经过期,仅为旧项目保留。新项目请使用[uni-id的外部系统联登](https://uniapp.dcloud.net.cn/uniCloud/uni-id-pages.html#external) +|API |描述 | +|-- |-- | +|getConversationList |获取会话列表[见下方](#coGetConversationList) | +|sendMsg |发送聊天消息[见下方](#coSendMsg) | +|sendPushMsg |触发器专用消息推送方法 | +|sendMsgToGroup |向群用户递归推送消息[见下方](#coSendMsgToGroup) | +|addFriendInvite |向用户发起加好友邀请[见下方](#coAddFriendInvite) | +|chooseUserIntoGroup |选择用户加入群聊(不传群id时为创建群)[见下方](#coSendMsgToGroup) | +|revokeMsg |撤回已经发送的消息[见下方](#coRevokeMsg) | -如果你的项目是基于非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位)。 -**接口形式** +### 获取会话列表 getConversationList@coGetConversationList +**参数说明** -```js -await uniImCo.loginWithJWT(signedData) -``` +|参数名 |类型 |必填 |说明 | +|-- |-- |-- |-- | +|limit |number |否 |数量,默认值:500 | +|maxUpdateTime |number |否 |最大更新时间(实现高性能分页) | +|page |number |是 |页码 | -signedData 为通过jwt签名后的数据 +**返回值** -> 各类计算机语言,jwt库下载地址:https://jwt.io/libraries +|参数名 |类型 |说明 | +|-- |-- |-- | +|errCode|string|number |错误码,0表示成功 | +|errMsg |string |错误信息 | +|data |array |会话数据 | -**signedData 包含的数据说明** +### 发送聊天消息 sendMsg@coSendMsg -| 字段 | 类型 |必填 | 描述 | -| -- | -- | -- | -- | -| exp | timestamp | 否 | 签名数据的过期时间 | -| userInfo | Object | 是 | 用户信息[详情](#signedDataUserInfo) | +|参数名 |类型 |必填 |说明 | +|-- |-- |-- |-- | +|appId |string |是 |接收消息的appId;如果你是2个不同appId的应用相互发,请修改此值为相对的appId | +|to_uid |string |否 |接收消息的用户id | +|group_id |string |否 |接收消息的群id| +|body |string |是 |消息内容,`type = text`时为文本内容.`type = image`时为图片网络地址| +|type |string |是 |消息类型,暂时仅支持:text(表示文本类型)、image(表示图片类型)| +|isRetries |Boolean|否 |是否为重发| -**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"]`表示为超级管理员,不受任何权限限制;| +|参数名 |类型 |说明 | +|-- |-- |-- | +|errCode |string|number |错误码,0表示成功 | +|errMsg |string |错误信息 | +|data |object | | +| |- create_time |无 |创建时间 | -签名密钥配置路径: `/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("签名验证失败") -} -*/ +const uniImCo = uniCloud.importObject('uni-im-co', { + customUI: true +}); +await uniImCo.sendMsg({ + to_uid:"630cacf46293d20001f3c368", + type:"text", + body:"您好!" +}) ``` +### 向群用户递归推送消息 sendMsgToGroup@coSendMsgToGroup +注意:这是一个递归云对象,500个设备为一组批量向用户推送消息(该方法仅支持云对象的方法,或者触发器调用) + +|参数名 |类型 |必填 |说明 | +|-- |-- |-- |-- | +|appId |string |是 |接收消息的应用appId| +|pushParam |object |是 |参数同uni-push2.0的sendMessage方法,详情参考[https://uniapp.dcloud.net.cn/uniCloud/uni-cloud-push/api.html#sendmessage](https://uniapp.dcloud.net.cn/uniCloud/uni-cloud-push/api.html#sendmessage)| +|before_id |string |否 |从哪个用户id开始(用于实现高性能分页)| +|push_clientids |array |否 |个推设备id列表| **返回值** |参数名 |类型 |说明 | |-- |-- |-- | -|errCode |string|number |错误码 | +|errCode |string|number |错误码,0表示成功 | |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) +### 撤回已发送的消息 revokeMsg@coRevokeMsg +|参数名 |类型 |必填 |说明 | +|-- |-- |-- |-- | +|msgId |string |是 |消息id | +**返回值** +|参数名 |类型 |说明 | +|-- |-- |-- | +|errCode |string|number |错误码,0表示成功 | +|errMsg |string |错误信息 | -#### 获取会话列表getConversationList@coGetConversationList -**参数说明** +### 向用户发起加好友邀请 addFriendInvite@coAddFriendInvite -|参数名 |类型 |必填 |说明 | -|-- |-- |-- |-- | -|limit |number |否 |数量,默认值:500 | -|page |number |是 |页码 | +|参数名 |类型 |必填 |说明 | +|-- |-- |-- |-- | +|to_uid |string |是 |被邀请的用户id| +|message |string |否 |请求信息| **返回值** -|参数名 |类型 |说明 | -|-- |-- |-- | -|errCode|string|number |错误码,0表示成功 | -|errMsg |string |错误信息 | -|data |array |会话数据 | +|参数名 |类型 |说明 | +|-- |-- |-- | +|errCode |string|number |错误码,0表示成功 | +|errMsg |string |错误信息 | + +### 选择用户加入群聊 chooseUserIntoGroup@coSendMsgToGroup -#### 发送聊天消息sendMsg@coSendMsg -|参数名 |类型 |必填 |说明 | -|-- |-- |-- |-- | -|to_uid |string |否 |接受消息的用户id | -|appId |string |是 |接收消息的appId;如果你是2个不同appId的应用相互发,请修改此值为相对的appId | -|type |string |是 |消息类型,暂时仅支持:text(表示文本类型)、image(表示图片类型)| -|body |string |是 |消息内容,`type = text`时为文本内容.`type = image`时为图片网络地址| +|参数名 |类型 |必填 |说明 | +|-- |-- |-- |-- | +|group_id |string |否 |群id(为空则创建群) | +|user_ids |string |是 |用户id数组 | **返回值** @@ -513,72 +429,140 @@ uni.request({ |-- |-- |-- | |errCode |string|number |错误码,0表示成功 | |errMsg |string |错误信息 | -|data |object | | -| |- create_time |无 |创建时间 | +|data |object |返回信息 | +| |- group_id |string |群id | -**接口形式** - -```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)| +|字段名 |数据类型 |说明 | +|-- |-- |-- | +|customer_service_uids |string/boolean |客服用户id,不限制则填`false`即可;仅conversation_grade的值为100时有效 | +|conversation_grade |int |控制发起会话的条件,详情[会话控制](#conversation_grade) | ### 会话控制@conversation_grade -|值 |说明 | -|-- |-- | -|0 |不限制 | +|值 |说明 | +|-- |-- | +|0 |不限制 | |100|仅限当前用户向:客服、好友、群成员发起会话 | -|200|仅限当前用户向:好友或群成员发起会话 | +|200|仅限当前用户向:好友或群成员发起会话 | ## 客户端sdk@clientSkd -### Vuex状态管理 -uni-im的数据通过Vuex进行状态管理,如果你不了解Vuex[详情参考](https://v3.vuex.vuejs.org/zh/)。 - -这种中心化响应式的数据管理,在用户切换聊天会话时,数据不会不重头加载;降低获取数据的网络请求次数,提高了效率,带来更好的用户体验。 -文件路径:`/uni_modules/uni-im/common/store.js` - -#### state +入口文件路径:`@/uni_modules/uni-im/lib/main.js` + +uni-im2.0 废弃了1.0通过Vuex的状态管理方式,不再需要关心vuex的用法,直接当做一个全局的响应式js变量即可。 + +### state + +|名称 |类型 |说明 | +|-- |-- |-- | +|conversation |object |会话对象 | +| |- dataList|array |会话数据列表 | +| |- hasMore |boolean |是否还有更多会话数据 | +|currentConversationId |string |正在对话的会话id | +|heartbeat |timestamp |心跳(精确到秒)详情:[心跳概念说明](#heartbeatExplain) | +|friend |object |好友对象 | +| |- dataList|array |好友数据列表 | +| |- hasMore |boolean |是否还有更多好友数据 | +|group |object |聊天群对象 | +| |- dataList|array |聊天群数据列表 | +| |- hasMore |boolean |是否还有更多群聊数据 | +|notification |object |系统通知对象 | +| |- dataList|array |系统通知数据列表 | +| |- hasMore |boolean |是否还有更多系统通知数据 | +|usersInfo |object |存储所有出现过的用户信息,包括群好友信息 | +|isWidescreen |boolean |是否为pc宽屏 | +|systemInfo |object |系统信息详情参考:[https://uniapp.dcloud.net.cn/api/system/info.html#系统信息的概念](https://uniapp.dcloud.net.cn/api/system/info.html#%E7%B3%BB%E7%BB%9F%E4%BF%A1%E6%81%AF%E7%9A%84%E6%A6%82%E5%BF%B5) | +|indexDB |object/boolean |indexDB对象(仅web端有效) | +|audioContext |object/boolean |audio对象 | +|dataBaseIsOpen |boolean |判断本地sqlite数据库是否已经打开(仅app端有用) | +|socketOpenIndex |number |记录socket打开次数(用于处理:从云端同步,socket意外断开期间丢失的数据使用) | + +心跳概念说明 heartbeat @heartbeatExplain +uni-im的会话列表和消息列表,需要显示实时的发生时间。而一个应用开启太多的定时器,会消耗大量的系统性能。 +所以uni-im提供了一个每秒钟更新一次的响应式数据`heartbeat`,由uniImInit方法:启用一个定时器刷新,挂载在全局,所有应用场景引用这一个变量即可 + +#### methods + +|名称 |说明 | +|-- |-- | +|conversation |会话对象 | +| |- get |获取会话数据 | +| |- loadMore |加载更多会话数据 | +| |- unreadCount |统计所有消息的未读数 | +| |- remove |删除会话 | +|notification |系统消息 | +| |- get |获取系统消息 | +| |- loadMore |加载更多系统消息 | +| |- unreadCount |统计未读数 | +|friend |好友列表 | +| |- get |获取好友数据 | +| |- loadMore |加载更多系统消息 | +|group |群列表 | +| |- get |获取群聊数据 | +| |- loadMore |加载更多群聊数据 | +|mergeUsersInfo |添加用户信息到本地用户信息库 | +|clearUnreadCount |设置某个会话的未读消息数为已读 | + + +使用示例: +```js +//引入uniImMethods +import uniIm from '@/uni_modules/uni-im/lib/main.js'; +``` -|名称 |类型 |说明 | -|-- |-- |-- | -|conversationDatas |object |由多个[会话对象](#conversation)组成,以会话id为key | -|currentConversationId |string |正在对话的会话id | -|heartbeat |timestamp |心跳(精确到秒) | +- 获取会话数据 -概念说明: +1. 获取全部会话数据 +```js +let param = null +let conversationList = await uniIm.conversation.get(param) +``` +2. 获取指定会话的id会话数据 +```js +//xxx表示会话id +let param = "xxx" +let conversationList = await uniIm.conversation.get(param) +``` +3. 获取指定好友id的会话数据(如果本地不存在则从云端拉取,仍然不存在则本地自动创建) +```js +//xxx表示好友id +let param = {"friend_uid":"xxx"}, +let conversationList = await uniIm.conversation.get(param) +``` +4. 获取指定群聊id的会话数据(如果本地不存在则从云端拉取,仍然不存在则本地自动创建) +```js +//xxx表示群聊id +let param = {"group_id":"xxx"} +let conversationList = await uniIm.conversation.get(param) +``` -##### 心跳 heartbeat -uni-im的会话列表和消息列表,需要显示实时的发生时间。而一个应用开启太多的定时器,会消耗大量的系统性能。 +- 加载会话数据 -所以uni-im提供了一个响应式数据`heartbeat`,挂载在Vuex,由uniImInit方法:用一个定时器刷新。 +1. 加载更多会话数据(分页加载,新数据的会话更新时间,小于列表中最小的会话更新时间) +```js +let param = null +let conversationList = await uniIm.conversation.loadMore(param) +``` +2. 加载指定会话id的会话数据 +```js +// xxx表示会话id +let param = 'xxx' +let conversationData = await uniIm.conversation.loadMore(param) +``` -##### 会话对象 conversation@conversation +**返回值** -|属性名 |类型 |说明 | -|-- |-- |-- | -|id |string |当前会话id | +|属性名 |类型 |说明 | +|-- |-- |-- | +|id |string |当前会话id | |title |string |普通会话为对方的用户名或昵称、群会话为群昵称 | |avatar_file |uniCloud file |普通会话为对方的用户头像、群会话为群头像 | -|owner_uid |string |所属用户id | |unread_count |number |未读消息数 | |user_id |string |对话的用户id(群聊会话时为空) | |group_id |string |对话的群聊id(普通会话时为空) | @@ -586,150 +570,141 @@ uni-im的会话列表和消息列表,需要显示实时的发生时间。而 |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 +let unreadCount = await uniIm.conversation.unreadCount() +``` -使用示例: +- 删除指定id的会话数据 ```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(); +// xxx表示会话id +let param = 'xxxx' +await uniIm.conversation.remove(param) ``` -|属性名 |类型 |说明 | -|-- |-- |-- | -|isInit |boolean |是否已经加载过首页数据 | -|getMore |function |获取更多历史聊天数据(如果数据来源服务端,会自动保存到storage) | -|pageLimit |number |配置的聊天数据分页值 | +- 获取系统消息数据 -### storage操作库 -uni-app的[数据缓存](https://uniapp.dcloud.net.cn/api/storage/storage.html#),是通过不同的key来存储和获取数据。 +1. 不限类型 +```js +let param = null +await uniIm.notification.get(param) +``` -如下示例: +2. 指定类型(单个) ```js -// 设置数据 -uni.setStorageSync('storage_key', 'hello'); -// 读取数据 -uni.getStorageSync('storage_key'); +// uni-im-group-join-request 表示加群通知 +let param = {type:"uni-im-friend-invite"} +await uniIm.notification.get(param) ``` -以不同的key值,单独存储一组数据; +3. 指定类型(多个) +```js +// uni-im-group-join-request uni-im-friend-invite 表示加群通知、好友加请求通知 +let param = {type:["uni-im-friend-invite","uni-im-friend-invite"]} +await uniIm.notification.get(param) +``` -而im聊天数据可能非常庞大,需要分页存储,且支持按时间和页码检索。 +4. 排除类型(单个) +```js +// uni-im-group-join-request 表示加群通知 +let param = {excludeType:"uni-im-friend-invite"} +await uniIm.notification.get(param) +``` -uni-im-storage应需而生,封装了这些方法: +5. 排除类型(多个) +```js +// uni-im-group-join-request uni-im-friend-invite 表示加群通知、好友加请求通知 +let param = {excludeType:["uni-im-friend-invite","uni-im-friend-invite"]} +await uniIm.notification.get(param) +``` -|方法名 |说明 | -|-- |-- | -|update |更新数据 [详见](#update) | -|getData|获取数据 [详见](#getData) | -|append |向某个会话的聊天数据中添加一条聊天数据(一般用于收到) | -|insert |向前插入数据 | +- 加载系统消息数据 +参数与`获取系统消息数据`一致 -uni-im-storage 还有一个可以配置的属性值`pageLimit`即:加载历史聊天数据时每一页的数据。 +- 获取好友数据 +```js +await uniIm.friend.get() +``` -配置方式,修改路径`/uni_modules/uni-im/common/uni-im-storage.js`第二行pageLimit的值(默认值:`30`)。 +- 加载更多好友数据 +1. 分页加载 +```js +await uniIm.friend.loadMore() +``` +2. 加载指定好友数据 +```js +let param = {"friend_uid":"xxx"} +await uniIm.friend.loadMore(param) +``` +- 删除好友数据 +```js +let param = {"friend_uid":"xxx"} +await uniIm.friend.remove(param) +``` -**update 参数说明**@updateMsgStorage +- 获取群聊数据 +```js +await uniIm.group.get() +``` -|参数名 |类型 |是否必填 |说明 | -|-- |-- |-- |-- | -|id |string |是 |消息id | -|data |object |是 |消息数据 | +- 加载更多群聊数据 +1. 分页加载 +```js +await uniIm.group.loadMore() +``` +2. 加载指定群聊数据 +```js +let param = {"group_id":"xxx"} +await uniIm.group.loadMore(param) +``` +- 删除群聊数据 +```js +let param = {"group_id":"xxx"} +await uniIm.group.remove(param) +``` -**getData 参数说明**@getData +- 添加用户信息到本地用户信息库 +```js +// xxx表示用户数据 +let usersInfo = {xxx} +await uniIm.mergeUsersInfo(usersInfo) +``` -|参数名 |类型 |是否必填 |说明 | -|-- |-- |-- |-- | -|conversation_id|string |是 |会话id | -|limit |object |否 |获取的条数,默认为配置的pageLimit的值 | -|page |object |page、maxTime、miniTime 三选一 |页码。支持负数,如:-1表示倒数第一页 | -|maxTime |object |page、maxTime、miniTime 三选一 |获取的消息的最大时间 | -|miniTime |object |page、maxTime、miniTime 三选一 |暂不支持 | +- 设置某个会话的未读消息数为已读 +```js +// xxx表示会话id +let conversation_id = "xxx" +await uniIm.clearUnreadCount(conversation_id) +``` #### 工具类库@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小时前等 | - +|名称 |类型 |说明 |入参 |返回值 | +|-- |-- |-- |-- |-- | +|init |function |初始化uni-im(监听聊天消息,定时每秒更新心跳值为当前时间戳) |无 |无 | +|getConversationId |function |获取会话id |对话的用户id或群id 详见[详见](#getConversationId) |无 | +|toFriendlyTime |function |用于将时间戳转友好时间提示(距离当前2小时内的时间戳,每隔一秒钟会刷新一次) |时间戳:timestamp |格式化后的时间字符串。如:x年x月x日,昨天,下午,1小时前等 | +|clearPushNotify |function |清空push消息栏通知 |无 |无 | +|login |function |非uni-id体系系统登录到uni-im方法 |时间戳:timestamp |参数为对象,含token和token过期时间,例如:`{"token":"xxx","tokenExpired":1679403132582}` | -## 项目升级 -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. 先执行: +- 获取会话id @getConversationId +1. 获取单聊会话id ```js -db.collection('uni-im-conversation').update({ - "user_id": db.command.rename('friend_uid') -}) +let friend_uid = "xxx" +uniIm.getConversationId(friend_uid,'single') ``` -2. 再执行:(**注意:不要两句一起执行,也别弄反顺序**) +2. 获取群聊会话id ```js -db.collection('uni-im-conversation').update({ - owner_uid: db.command.rename('user_id') -}) +let group_id = "xxx" +uniIm.getConversationId(group_id,'group') ``` ->此版本新增`会话控制`配置,[详情查看](#conversation_grade) +## 项目升级 +uni-im遵循uni-app的插件模块化规范,即:[uni_modules](https://uniapp.dcloud.io/uni_modules)。 +在项目根目录下的`uni_modules`目录下,以插件ID即`uni-im`为插件文件夹命名,在该目录右键也会看到“从插件市场更新”选项,点击即可更新该插件。也可以用插件市场web界面下载覆盖。 ## 许可协议 -- GitLab