Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
qq_16800119
unidocs-zh
提交
06b0cf73
unidocs-zh
项目概览
qq_16800119
/
unidocs-zh
与 Fork 源项目一致
Fork自
DCloud / unidocs-zh
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
unidocs-zh
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
06b0cf73
编写于
4月 14, 2023
作者:
DCloud_JSON
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Update uni-im.md
上级
13c6e5fa
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
377 addition
and
402 deletion
+377
-402
docs/uniCloud/uni-im.md
docs/uniCloud/uni-im.md
+377
-402
未找到文件。
docs/uniCloud/uni-im.md
浏览文件 @
06b0cf73
> 本
插件需要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控制台,更改
`连接本地云函数`
为
`连接云端云函数`
<img
width=
"600px"
src=
"https://dcloud-chjh-web.oss-cn-hangzhou.aliyuncs.com/ext/uni-im/20230317211717.jpg"
></img>
5.
`运行项目`
到2个不同的浏览器,因为在同一个浏览器打开相同网络地址(ip或者域名)的uni-im项目,socket会相互占线。
所以需要使用两个浏览器(或者使用浏览器
`打开新的无痕式窗口`
功能充当第二个浏览器)分别
`注册账号并登录`
,
到此部署已经结束
...
...
@@ -121,67 +120,12 @@ uni-im本身并不收费,实际使用中需要依赖uniCloud云服务,会产
</script>
```
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则表示不限制。
# 开发文档
## 目录结构
<pre
v-pre=
""
data-lang=
""
>
<code
class=
"lang-"
style=
"padding:0"
>
├─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 插件自述文件
</code>
</pre>
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 为通过
<a
target=
"_blank"
href=
"https://jwt.io"
>
jwt
</a>
签名后的数据
**返回值**
> 各类计算机语言,jwt库下载地址:<a target="_blank" href="https://jwt.io/libraries">https://jwt.io/libraries</a>
|参数名 |类型 |说明 |
|-- |-- |-- |
|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
)
。
<br/>
当值为:
`["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,
</br>
会自动将新token及过期时间存储在storage内。
</br>
当客户端调用云函数(云对象)的方法时,会自动带上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界面下载覆盖。
## 许可协议
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录