Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wangjie868686
hello uni-im
提交
ce2ad049
H
hello uni-im
项目概览
wangjie868686
/
hello uni-im
与 Fork 源项目一致
Fork自
DCloud / hello uni-im
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
H
hello uni-im
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
ce2ad049
编写于
11月 25, 2022
作者:
DCloud_JSON
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
1.2.1 修复 某些情况下 非uniCloud 开发的项目 接入uni-im 登录后会话列表不更新的问题
上级
6ccbab61
变更
23
隐藏空白更改
内联
并排
Showing
23 changed file
with
463 addition
and
365 deletion
+463
-365
.gitignore
.gitignore
+2
-1
.npmignore
.npmignore
+2
-1
App.vue
App.vue
+9
-20
README.md
README.md
+78
-65
uniCloud-aliyun/database/newQuery.jql
uniCloud-aliyun/database/newQuery.jql
+3
-3
uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json
...loudfunctions/common/uni-config-center/uni-id/config.json
+1
-1
uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-im/config.json
...loudfunctions/common/uni-config-center/uni-im/config.json
+2
-1
uni_modules/uni-id-pages/components/cloud-image/cloud-image.vue
...dules/uni-id-pages/components/cloud-image/cloud-image.vue
+1
-1
uni_modules/uni-id-pages/config.js
uni_modules/uni-id-pages/config.js
+1
-1
uni_modules/uni-im/changelog.md
uni_modules/uni-im/changelog.md
+14
-2
uni_modules/uni-im/common/store.js
uni_modules/uni-im/common/store.js
+12
-8
uni_modules/uni-im/common/utils.js
uni_modules/uni-im/common/utils.js
+49
-23
uni_modules/uni-im/components/uni-im-msg/uni-im-msg.vue
uni_modules/uni-im/components/uni-im-msg/uni-im-msg.vue
+2
-1
uni_modules/uni-im/package.json
uni_modules/uni-im/package.json
+3
-2
uni_modules/uni-im/pages/chat/chat.nvue
uni_modules/uni-im/pages/chat/chat.nvue
+29
-30
uni_modules/uni-im/pages/index/index.nvue
uni_modules/uni-im/pages/index/index.nvue
+190
-170
uni_modules/uni-im/pages_init.json
uni_modules/uni-im/pages_init.json
+1
-1
uni_modules/uni-im/readme.md
uni_modules/uni-im/readme.md
+0
-2
uni_modules/uni-im/uniCloud/cloudfunctions/uni-im-co/index.obj.js
...les/uni-im/uniCloud/cloudfunctions/uni-im-co/index.obj.js
+46
-28
uni_modules/uni-list/changelog.md
uni_modules/uni-list/changelog.md
+10
-0
uni_modules/uni-list/components/uni-list-chat/uni-list-chat.vue
...dules/uni-list/components/uni-list-chat/uni-list-chat.vue
+2
-2
uni_modules/uni-list/components/uni-list-item/uni-list-item.vue
...dules/uni-list/components/uni-list-item/uni-list-item.vue
+5
-1
uni_modules/uni-list/package.json
uni_modules/uni-list/package.json
+1
-1
未找到文件。
.gitignore
浏览文件 @
ce2ad049
...
...
@@ -10,4 +10,5 @@ uni_modules.config.json
vite.config.js
vue.config.js
.DS_Store
!/uni_modules/uni-im/node_modules/blueimp-md5/
\ No newline at end of file
!/uni_modules/uni-im/node_modules/blueimp-md5/
!/uni_modules/uni-im/node_modules/blueimp-md5
\ No newline at end of file
.npmignore
浏览文件 @
ce2ad049
...
...
@@ -9,4 +9,5 @@ uni_modules.config.json
/cloud_function_publish
vite.config.js
vue.config.js
!/uni_modules/uni-im/node_modules/blueimp-md5/
\ No newline at end of file
!/uni_modules/uni-im/node_modules/blueimp-md5/
!/uni_modules/uni-im/node_modules/blueimp-md5
\ No newline at end of file
App.vue
浏览文件 @
ce2ad049
<
script
>
import
uniIdPagesinit
from
'
@/uni_modules/uni-id-pages/init.js
'
;
//1. 导入uniIm的Utils工具类
<
script
>
//1. 导入uni身份信息管理模块
import
uniIdPagesInit
from
'
@/uni_modules/uni-id-pages/init.js
'
;
//2. 导入uniIm的Utils工具类
import
uniImUtils
from
'
@/uni_modules/uni-im/common/utils.js
'
;
export
default
{
globalData
:
{
//2. 初始化uniIm全局变量
uniIm
:
{
msgManagers
:
{},
//app是否显示在前台
appIsShow
:
false
}
},
onLaunch
:
async
function
()
{
console
.
log
(
'
App Launch
'
);
uniIdPagesinit
();
//3.初始化uniIm
//3. 初始化uni身份信息管理模块
uniIdPagesInit
();
//4. 初始化uniIm
uniImUtils
.
init
();
},
onShow
:
function
()
{
// 4.在onShow生命周期,更改全局变量中app是否显示在前台为true
this
.
globalData
.
uniIm
.
appIsShow
=
true
;
console
.
log
(
'
App Show
'
);
// 5.清理系统通知栏消息和app角标
uniImUtils
.
clearPushNotify
()
},
onHide
:
function
()
{
//6.在onHide生命周期,更改全局变量中app是否显示在前台为false
this
.
globalData
.
uniIm
.
appIsShow
=
false
;
console
.
log
(
'
App Hide
'
);
}
};
</
script
>
<
style
>
/*每个页面公共css */
/* #ifndef APP-NVUE */
@import
"@/uni_modules/uni-im/static/iconfont.css"
;
/* #endif */
/*每个页面公共css */
</
style
>
README.md
浏览文件 @
ce2ad049
> 本插件
需要HBuilderX 3.6.9 及其以上版本支持
> 本插件
APP端需要HBuilderX 3.6.9 及其以上版本支持,微信小程序和网页端需要HBuilderX 3.6.4 及其以上版本支持。
# 简介
uni-im是云端一体的、全平台的、免费的、开源即时通讯系统。
...
...
@@ -54,46 +54,30 @@ uni-im是云端一体的、全平台的、免费的、开源即时通讯系统
## 部署到自己的项目
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文件,进行如下操作:
-
导入uniIm的Utils
-
初始化uniIm
-
在globalData中添加预置数据
-
在onShow和onHide生命周期更改app是否显示在前台的值
3.
打开项目根目录的App.vue文件,初始化uni-id-pages和uniIm模块
示例如下:
```
html
<script>
import
uniIdPagesinit
from
'
@/uni_modules/uni-id-pages/init.js
'
;
//1. 导入uniIm的Utils工具类
//1. 导入uni身份信息管理模块
import
uniIdPagesInit
from
'
@/uni_modules/uni-id-pages/init.js
'
;
//2. 导入uniIm的Utils工具类
import
uniImUtils
from
'
@/uni_modules/uni-im/common/utils.js
'
;
export
default
{
globalData
:{
//2. 初始化uniIm全局变量
uniIm
:{
msgManagers
:{},
//app是否显示在前台
appIsShow
:
false
}
},
onLaunch
:
function
()
{
onLaunch
:
async
function
()
{
console
.
log
(
'
App Launch
'
);
uniIdPagesinit
();
//3.初始化uniIm
//3. 初始化uni身份信息管理模块
uniIdPagesInit
();
//4. 初始化uniIm
uniImUtils
.
init
();
},
onShow
:
function
()
{
//4.在onShow生命周期,更改全局变量中app是否显示在前台为true
this
.
globalData
.
uniIm
.
appIsShow
=
true
//5.清理系统通知栏消息和app角标
uniImUtils
.
clearPushNotify
()
console
.
log
(
'
App Show
'
)
console
.
log
(
'
App Show
'
);
},
onHide
:
function
()
{
//6.在onHide生命周期,更改全局变量中app是否显示在前台为false
this
.
globalData
.
uniIm
.
appIsShow
=
false
console
.
log
(
'
App Hide
'
)
console
.
log
(
'
App Hide
'
);
}
}
}
;
</script>
```
...
...
@@ -152,41 +136,54 @@ uni-im是云端一体的、全平台的、免费的、开源即时通讯系统
export
default
store
```
5.
账号登录;用户体系基于不同技术实现的项目,登录要求不同:
-
基于
`uni-id-pages`
开发的项目,直接登录即可。
-
基于老版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
)
}
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
})
```
2.
在登录成功和用户信息更新时,同步更新uniId store内的当前用户信息(uni-im显示当前用户头像、昵称时会用到)示例代码:
```
js
//导入uniCloud客户端账户体系,用户信息状态管理模块
import
{
mutations
as
uniIdMutations
}
from
'
@/uni_modules/uni-id-pages/common/store.js
'
;
await
uniIdMutations
.
updateUserInfo
()
```
-
基于非uniCloud开发的项目(比如:应用服务端的开发语言是php、java、go、c#等,用户信息并没未存储在uniCloud云数据库中)需要通过uni-im-co的loginWithJWT方法实现登录
[
详情查看
](
#uniImCoLoginWithJWT
)
。
6.
接下来打开,“用户列表页”(路径:
`/uni_modules/uni-im/pages/userList/userList`
)可以看到所有的注册用户。
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`
)可以看到所有的注册用户。
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开发的项目可忽略)
**补充:**
(基于uni-id-pages开发的项目可忽略)
为了实现用户退出登录后,不再收到im消息,需要在执行退出登录时同步状态给uni-id-pages。示例代码如下:
```
js
import
{
mutations
as
uniIdMutations
}
from
'
@/uni_modules/uni-id-pages/common/store.js
'
...
...
@@ -201,13 +198,20 @@ uniIdMutations.logout()
逻辑代码如下:
```
js
uni
.
navigateTo
({
url
:
'
/uni_modules/uni-im/pages/chat/chat?user_id
'
+
对应的用户id
url
:
'
/uni_modules/uni-im/pages/chat/chat?user_id
=
'
+
对应的用户id
})
```
-
服务端限制
打开
`uni-im-co`
路径:
`/uni_modules/uni-im/uniCloud/cloudfunctions/uni-im-co/index.obj.js`
配置第一行
`admin_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则表示不限制。
# 开发文档
## 目录结构
...
...
@@ -248,9 +252,9 @@ uni-im v1.0.0 暂时比较简单,云端有1个云对象`uni-im-co`,2个opend
名词解释
-
聊天会话ID
根据通讯双方用户id,生成
唯一索引;通过该索引值,查询双方的聊天记录等信息。
根据通讯双方用户id,生成
的唯一索引值;
-
聊天会话
以会话ID为索引的一组数据,记录:未读消息数量、会话
类型、所属用户id、对话的用户id、对话的群id、未读消息数量、最后一条消息概述(文本消息的前15个字,消息为多媒体时只描述类型)、最后一条消息时间
以会话ID为索引的一组数据,记录:未读消息数量、会话
更新时间、会话类型、会话所属用户的id、对话的用户id、对话的群id、最后一条消息概述(文本消息的前15个字,消息为多媒体时只描述类型)
## uni-im-co 云函数(云对象)
### API列表
...
...
@@ -262,8 +266,15 @@ uni-im v1.0.0 暂时比较简单,云端有1个云对象`uni-im-co`,2个opend
#### 账号登录loginWithJWT@uniImCoLoginWithJWT
如果你的项目是基于非uniCloud开发的项目(比如:应用服务端的开发语言是php、java、go、c#等,用户信息并没未存储在uniCloud云数据库中)需要通过
基于跨平台签名认证的方式,向uniCloud账户体系新增用户(创建过则更新用户信息)并获取token实现登录的方法。
如果你的项目是基于非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位)。
**接口形式**
...
...
@@ -341,6 +352,8 @@ try{
**示例代码:**
以下为客户端的示例,演示了在客户端中登录之前的账户体系成功后,把signedData传给uni-im,调用uni-im的联登接口。
```
js
// 1. 导入uniCloud客户端账户体系,用户信息状态管理模块
import
{
...
...
@@ -633,4 +646,4 @@ d) 如您违反本许可协议,需承担因此给DCloud造成的损失。
根据发展,DCloud可能会对本协议进行修改。修改时,DCloud会在产品或者网页中显著的位置发布相关信息以便及时通知到用户。如果您选择继续使用本框架,即表示您同意接受这些修改。
条款结束
\ No newline at end of file
条款结束
uniCloud-aliyun/database/newQuery.jql
浏览文件 @
ce2ad049
...
...
@@ -8,9 +8,9 @@
// 数据库查询有最大返回条数限制,详见:https://uniapp.dcloud.net.cn/uniCloud/cf-database?id=limit
// 详细JQL语法,请参考 https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=jsquery
db.collection('uni-im-
msg
').where({
conversation_id:"single_5ecba2763bd858474c014870965d93c5
"
}).
get
()
db.collection('uni-im-
conversation
').where({
id: "single_1ba6a8117d7706a8f26204cf87245871
"
}).
remove
()
// 下面示例查询uni-id-users表的所有数据
...
...
uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json
浏览文件 @
ce2ad049
{
"passwordSecret"
:
"passwordSecret-demo"
,
"tokenSecret"
:
"passwordSecret-demo"
,
"passwordStrength"
:
"
medium
"
,
"passwordStrength"
:
""
,
"tokenExpiresIn"
:
7200
,
"tokenExpiresThreshold"
:
600
,
"passwordErrorLimit"
:
6
,
...
...
uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-im/config.json
浏览文件 @
ce2ad049
{
"jwtSecret"
:
"jwtSecretDemo"
"jwtSecret"
:
"jwtSecretDemo"
,
"admin_uid"
:
false
}
uni_modules/uni-id-pages/components/cloud-image/cloud-image.vue
浏览文件 @
ce2ad049
...
...
@@ -52,7 +52,7 @@
watch
:
{
src
:{
handler
(
src
)
{
if
(
src
.
includes
(
'
://
'
)
){
if
(
src
.
substr
(
0
,
8
)
==
'
cloud://
'
){
uniCloud
.
getTempFileURL
({
fileList
:
[
src
]
}).
then
(
res
=>
{
...
...
uni_modules/uni-id-pages/config.js
浏览文件 @
ce2ad049
...
...
@@ -52,5 +52,5 @@ export default {
* weak(弱:密码必须包含字母和数字,长度范围:6-16位之间)
* 为空或false则不验证密码强度
*/
"
passwordStrength
"
:
"
medium
"
"
passwordStrength
"
:
""
}
uni_modules/uni-im/changelog.md
浏览文件 @
ce2ad049
## 1.1.0(2022-11-17)
新增 提供 非uniCloud(比如:应用服务端的开发语言是php、java、go、c#、python等)或 基于老版uni-id 开发的项目 接入uni-im的支持
## 1.2.1(2022-11-25)
-
修复 某些情况下 非uniCloud 开发的项目 接入uni-im 登录后会话列表不更新的问题
## 1.2.0(2022-11-23)
-
【重要】全端支持Vue3
-
修复 当历史消息超长时,APP端键盘弹起,不能滚动到最后一条消息
-
修复 键盘收起时,会自动滚动到最后一条消息的问题
-
修复 部分情况下,切换登录的账号,会话列表没有更新的问题
## 1.1.2(2022-11-21)
修复 某些情况下 iOS端 输入框内容发生变化时 页面重新排版,导致输入框被键盘挡住的问题
## 1.1.1(2022-11-18)
修复 向长时间未登录的用户(push_clientid已过期)发送消息,引起的报错问题。将数据写入云数据库,当用户再次登录时从服务端拉取
## 1.1.0(2022-11-18)
-
新增 支持 非uniCloud(比如:应用服务端的开发语言是php、java、go、c#、python等)或 不基于uni-id-pages 开发的项目 接入uni-im
-
简化部署流程 app.vue 页面仅需init uni-im即可(更加模块化,内部:监听应用生命周期onShow、onHidden实现相关功能、初始化依赖的globalData等)
## 1.0.3(2022-11-15)
降低uni-im使用的HBuilderX版本为
`3.6.4`
。 注意
**APP端**
:仅支持Vue2,且HBuilderX的版本为3.6.9+,否则chat页面存在滚动锚定问题(后续会修复此问题)
## 1.0.2(2022-11-14)
...
...
uni_modules/uni-im/common/store.js
浏览文件 @
ce2ad049
...
...
@@ -58,11 +58,6 @@ export default {
if
(
item
.
chatText
&&
state
.
currentConversationId
==
key
){
item
.
update_time
=
Date
.
now
()
}
if
(
!
item
.
update_time
){
// 插件市场项目补丁 时间字段错误
item
.
update_time
=
item
.
last_time
}
conversationList
.
push
(
item
)
}
conversationList
=
conversationList
.
sort
(
function
(
a
,
b
)
{
...
...
@@ -87,6 +82,9 @@ export default {
},
mergeConversationDatas
(
state
,
val
)
{
state
.
conversationDatas
=
Object
.
assign
({},
state
.
conversationDatas
,
val
)
},
clearConversationDatas
(
state
){
state
.
conversationDatas
=
{}
},
updateConversation
(
state
,
[
id
,
data
,
cover
=
false
])
{
let
conversationDatas
=
state
.
conversationDatas
...
...
@@ -168,15 +166,21 @@ export default {
}).
then
(
e
=>
{
console
.
log
(
'
设置为已读
'
,
e
.
result
.
updated
);
})
},
async
initConversationData
(
context
){
getConversationDatasPage
=
0
getApp
().
globalData
.
uniIm
=
{
"
msgManagers
"
:{}}
await
context
.
commit
(
'
clearConversationDatas
'
)
await
context
.
dispatch
(
'
loadMoreConversation
'
)
},
async
loadMoreConversation
(
context
,
conversation_id
)
{
const
uniImCo
=
uniCloud
.
importObject
(
"
uni-im-co
"
)
const
uniImCo
=
uniCloud
.
importObject
(
"
uni-im-co
"
,{
customUI
:
true
}
)
let
res
=
await
uniImCo
.
getConversationList
({
page
:
getConversationDatasPage
,
limit
:
this
.
limit
,
limit
:
30
,
conversation_id
})
// console.log('loadMoreConversation',
conversation_id,res.data
);
// console.log('loadMoreConversation',
{conversation_id,res}
);
if
(
res
.
data
.
length
){
getConversationDatasPage
++
//查到会话列表数据后转化格式
...
...
uni_modules/uni-im/common/utils.js
浏览文件 @
ce2ad049
// #ifdef APP
let
{
uniCompileVersion
}
=
uni
.
getSystemInfoSync
()
let
versionArr
=
uniCompileVersion
.
split
(
'
.
'
).
join
(
''
)
if
(
versionArr
[
0
]
<
3
||
(
versionArr
[
0
]
==
3
&&
versionArr
[
1
]
<
6
)
||
(
versionArr
[
0
]
==
3
&&
versionArr
[
1
]
==
6
&&
versionArr
[
2
]
<
9
)
){
uni
.
showModal
({
content
:
'
APP端uni-im需要HBuilderX 3.6.9以上版本,否则chat页面会存在滚动锚定问题
'
,
showCancel
:
false
});
}
// #endif
// #ifdef VUE3 && APP-NVUE
uni
.
showModal
({
content
:
'
uni-im APP端暂不支持Vue3,否则chat页面会存在滚动锚定问题
'
,
showCancel
:
false
});
// #ifdef VUE3
import
{
onShow
}
from
'
@dcloudio/uni-app
'
import
{
onHide
}
from
'
@dcloudio/uni-app
'
// #endif
import
md5
from
'
@/uni_modules/uni-im/node_modules/blueimp-md5
'
import
$store
from
'
@/store/index.js
'
import
formatTime
from
'
@/uni_modules/uni-im/common/formatTime
'
;
let
appIsShow
=
true
;
export
default
{
init
(){
//目前功能还比较简单,只有启用监听聊天数据和时间戳心跳(定时器)
setTimeout
(()
=>
{
// 初始化uniIm依赖的全局变量
getApp
().
globalData
.
uniIm
=
{
"
msgManagers
"
:{}}
},
0
)
//监听im消息
this
.
listenImMsg
()
//时间戳心跳(定时器)用于刷新:消息或会话与当前的时间差
setInterval
(()
=>
{
$store
.
commit
(
'
uniIm/updateHeartbeat
'
)
},
1000
)
// #ifdef APP
//提示兼容性问题
showTip
()
const
appOnShow
=
()
=>
{
appIsShow
=
true
//清理系统通知栏消息和app角标
this
.
clearPushNotify
()
}
function
appOnHide
(){
appIsShow
=
false
}
// #ifdef VUE2
getApp
().
$vm
.
$on
(
'
hook:onShow
'
,
appOnShow
)
getApp
().
$vm
.
$on
(
'
hook:onHide
'
,
appOnHide
)
// #endif
// #ifdef VUE3
onShow
(
appOnShow
,
getApp
().
$vm
.
$
)
onHide
(
appOnHide
,
getApp
().
$vm
.
$
)
// #endif
// #endif
},
getConversationId
(
param
,
type
=
'
single
'
)
{
//single,group
if
(
type
==
'
single
'
)
{
...
...
@@ -61,8 +72,7 @@ export default {
let
currentPages
=
getCurrentPages
()
let
topViewRoute
=
currentPages
[
currentPages
.
length
-
1
].
route
console
.
log
(
'
topViewRoute
'
,
topViewRoute
);
let
isShow
=
getApp
().
globalData
.
uniIm
.
appIsShow
if
(
!
isShow
||
!
[
'
uni_modules/uni-im/pages/index/index
'
,
'
uni_modules/uni-im/pages/chat/chat
'
].
includes
(
topViewRoute
)
){
if
(
!
appIsShow
||
!
[
'
uni_modules/uni-im/pages/index/index
'
,
'
uni_modules/uni-im/pages/chat/chat
'
].
includes
(
topViewRoute
)
){
console
.
log
(
'
payload
'
,
payload
);
let
{
content
,
data
,
title
,
avatar_file
}
=
payload
let
url
=
avatar_file
?
avatar_file
.
url
:
''
...
...
@@ -115,3 +125,19 @@ export default {
// #endif
}
}
function
showTip
(){
// #ifdef APP
let
{
uniCompileVersion
}
=
uni
.
getSystemInfoSync
()
let
version
=
uniCompileVersion
.
split
(
'
.
'
).
reduce
((
prev
,
cur
,
index
,
arr
)
=>
prev
+
cur
*
Math
.
pow
(
1000
,
arr
.
length
-
index
),
0
)
// console.log('version',version);
if
(
version
<
3006009000
){
uni
.
showModal
({
content
:
'
APP端uni-im需要HBuilderX 3.6.9以上版本,否则chat页面会存在滚动锚定问题
'
,
showCancel
:
false
});
}
// #endif
}
\ No newline at end of file
uni_modules/uni-im/components/uni-im-msg/uni-im-msg.vue
浏览文件 @
ce2ad049
...
...
@@ -22,7 +22,7 @@
<!-- #ifndef APP-NVUE -->
<view
class=
"text-box"
:class=
"msgClass"
>
<template
v-if=
"msg.body == htmlString"
>
<text
class=
"msg-text"
v-text=
"msg.body"
>
</text>
<text
class=
"msg-text"
>
{{
msg
.
body
}}
</text>
</
template
>
<
template
v-else
>
<template
v-for=
"(item,index) in nodes"
>
...
...
@@ -371,6 +371,7 @@
.link
{
// font-size: 16px;
color
:
#007fff
;
cursor
:
pointer
;
}
.self-text-box
{
...
...
uni_modules/uni-im/package.json
浏览文件 @
ce2ad049
{
"id"
:
"uni-im"
,
"displayName"
:
"uni-im"
,
"version"
:
"1.
0.3
"
,
"version"
:
"1.
2.1
"
,
"description"
:
"uni-im是云端一体的、全平台的、免费的、开源即时通讯系统"
,
"keywords"
:
[
"uni-im,即时通讯,客服,聊天"
...
...
@@ -32,7 +32,8 @@
},
"uni_modules"
:
{
"dependencies"
:
[
"uni-id-pages"
"uni-id-pages"
,
"uni-config-center"
],
"encrypt"
:
[],
"platforms"
:
{
...
...
uni_modules/uni-im/pages/chat/chat.nvue
浏览文件 @
ce2ad049
<template>
<view class="page">
<!-- #if
ndef APP-NVUE
-->
<!--
非nvue
端 左上角显示未读消息数 ,nvue端setTitleNViewButton-->
<!-- #if
def H5
-->
<!--
H5
端 左上角显示未读消息数 ,nvue端setTitleNViewButton-->
<view @click="tapUnreadCount" class="unread_count" v-if="unread_count != 0">
{{ unread_count > 99 ? '99+' : unread_count }}
</view>
...
...
@@ -9,9 +9,8 @@
<view class="msg-list-box">
<!-- 消息列表 -->
<uni-list ref="msg-list" class="msg-list" @touchstart="touchList" :show-scrollbar="false" :border="false"
render-reverse>
<uni-list-item class="item" v-for="(msg, index) in msgList" :key="msg.id" :border="false"
<uni-list ref="msg-list" class="msg-list" @touchstart="touchList" :show-scrollbar="false" :border="false" :render-reverse="true">
<uni-list-item class="item" v-for="(msg, index) in msgList" :key="msg.id" :border="false" :keep-scroll-position="true"
:customStyle='{"padding":0,"backgroundColor":"transparent"}'>
<template v-slot:body>
<view>
...
...
@@ -30,16 +29,14 @@
</uni-list-item>
<!-- #ifdef APP-NVUE -->
<cell v-if="systemInfo.platform == 'android' || msgList.length" keep-scroll-position
render-reverse-position>
<cell v-if="systemInfo.platform == 'android' || msgList.length" :keep-scroll-position="true" :render-reverse-position="true">
<!-- <text ref="msg-item" class="cell">这是最底部的一条</text> -->
</cell>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<!-- 非nvue端(是上下颠倒的),分页加载历史聊天数据 -->
<uni-list-item v-if="msgList.length" :border="false"
:customStyle='{"padding":0,"backgroundColor":"transparent"}'>>
<uni-list-item v-if="msgList.length" :border="false" :customStyle='{"padding":0,"backgroundColor":"transparent"}'>>
<template v-slot:body>
<text v-if="isSafariPc" @click="loadMore"
class="loadMore">{{ hasMore ? '点击加载更多' : '没有更多历史消息' }}</text>
...
...
@@ -62,7 +59,7 @@
<view class="tool-bar">
<uni-icons @click="sendImg" size="26px" type="image"></uni-icons>
</view>
<textarea maxlength="
40
0" v-model="chatText"></textarea>
<textarea maxlength="
25
0" v-model="chatText"></textarea>
</view>
<template v-else>
<!-- 切换为语音模式 -->
...
...
@@ -70,7 +67,7 @@
<view class="textarea-box">
<textarea v-model="chatText" @input="input" @confirm="beforeSendMsg" @linechange="linechange"
:style="{ height: textareaHeight + 'px' }" disable-default-padding hold-keyboard confirm-hold
auto-blur confirm-type="send" :show-confirm-bar="false" :cursor-spacing="
40" maxlength="40
0"
auto-blur confirm-type="send" :show-confirm-bar="false" :cursor-spacing="
20" maxlength="25
0"
class="textarea" ref="input-box" />
</view>
<!-- prevent实现,移动端 点击发送按钮,软键盘不自动收起 -->
...
...
@@ -216,17 +213,8 @@
text: unread_count == 0 ? '' : unread_count,
background: '#E5E5E5'
});
},
// #endif
currentConversation(data) {
// console.log(11231133123213,data);
if (data && data.title) {
//设置标题栏文字
uni.setNavigationBarTitle({
title: data.title
});
}
}
// #endif
},
beforeCreate() {
// #ifdef H5
...
...
@@ -267,8 +255,10 @@
// 监听键盘高度变化显示最后一条消息
uni.onKeyboardHeightChange(({
height
}) => {
this.showLast(0);
}) => {
if(height){
this.showLast(0);
}
});
// #endif
...
...
@@ -358,9 +348,9 @@
let text = clipboardData.getData('text');
if (text) {
console.log(text);
if (text.length >
40
0) {
if (text.length >
25
0) {
uni.showModal({
content: '你粘贴的文本长度超过
40
0,将被截断。',
content: '你粘贴的文本长度超过
25
0,将被截断。',
complete: e => {
if (!e.confirm) {
setTimeout(() => {
...
...
@@ -447,7 +437,7 @@
oldScrollTop = e.scrollTop;
},
async onLoad(e) {
//
console.log('onLoad', e, e.conversation_id,this.msgList.length);
//console.log('onLoad', e, e.conversation_id,this.msgList.length);
if (!e.conversation_id && e.user_id) {
e.conversation_id = uniImUtils.getConversationId(e.user_id)
if(!this.conversation(e.conversation_id)){
...
...
@@ -466,7 +456,7 @@
//设置当前会话id
//设置全局的app当前正在聊天的会话id
this.setCurrentConversationId(conversation_id);
this.setCurrentConversationId(conversation_id);
this.conversation_id = conversation_id;
if (!this.currentConversation.id) {
...
...
@@ -477,7 +467,10 @@
icon: 'none'
});
}
}
}
uni.setNavigationBarTitle({
title: this.currentConversation.title
});
//清除未读数
if (this.currentConversation.unread_count) {
this.clearUnreadCount(this.conversation_id);
...
...
@@ -809,7 +802,7 @@
// console.log('滚动到', this.msgList[this.msgList.length - 1].body);
dom.scrollToElement(target, {
animated: duration != 0,
offset:
500
offset:
999999
});
// #endif
...
...
@@ -963,7 +956,13 @@
/* #ifdef H5 */
margin-top: 45px;
/* #endif */
}
}
/* #ifdef MP */
.msg-list-box ::v-deep .uni-list{
background-color: transparent;
}
/* #endif */
/* #ifndef APP */
@media screen and (max-width: 960px) {
...
...
uni_modules/uni-im/pages/index/index.nvue
浏览文件 @
ce2ad049
<template>
<view id="page">
<view id="page">
<!-- <uni-list>
<uni-list-item title="新的朋友" thumb="/static/im-conversation/add.jpg" to="./add/add"></uni-list-item>
</uni-list> -->
...
...
@@ -30,22 +30,22 @@
<!-- #endif -->
<!-- #ifdef H5 -->
<scroll-view id="user-list-box" scroll-y="true" @scrolltolower="loadMore">
<!-- #endif -->
<!-- 会话用户列表 -->
<scroll-view id="user-list-box" scroll-y="true" @scrolltolower="loadMore
()
">
<!-- #endif -->
<!-- 会话用户列表 -->
<uni-list class="user-list" :style="{'height':wHeight,'width':'750rpx'}">
<uni-list-chat v-for="(item,index) in conversationList" :key="item.id"
:showBadge="item.unread_count>0" :badgeText="item.unread_count" link :title="item.title"
class="item" :class="{active:currentConversationId==item.id}" :note="item.last_msg_note"
:avatar="item.avatar_file ? item.avatar_file.url : '/uni_modules/uni-im/static/avatarUrl.png'"
:avatar="item.avatar_file
&&item.avatar_file.url
? item.avatar_file.url : '/uni_modules/uni-im/static/avatarUrl.png'"
@click="toChat(item.id)" direction="column" :time="formatTime(item.update_time)">
</uni-list-chat>
<!-- #ifdef APP-NVUE -->
<!-- nvue端appear(元素一旦显示在可视窗口中)就触发加载更多。-->
<cell v-if="conversationList.length" @appear="loadMore"></cell>
<cell v-if="conversationList.length" @appear="loadMore
()
"></cell>
<!-- #endif -->
</uni-list>
<!-- #ifdef H5 -->
<!-- #ifdef H5 -->
</scroll-view>
<!-- #endif -->
</view>
...
...
@@ -58,10 +58,9 @@
{{conversationDatas[currentConversationId].title}}
</block>
</view>
<scroll-view id="chat-view" :scroll-
into-view="scrollIntoView" :scroll-
top="scrollTop"
<scroll-view id="chat-view" :scroll-top="scrollTop"
@scroll="onScroll" scroll-y :lower-threshold="100">
<chat-view ref="chat-view" @setScroll="scrollTop = $event"></chat-view>
<text id="last-chat-view"></text>
</scroll-view>
</view>
</match-media>
...
...
@@ -93,14 +92,14 @@
// #endif
watch: {
isWidescreen(isWidescreen) {
this.setStyle()
if
(isWidescreen){
uni.hideTabBar()
}
else{
uni.showTabBar()
this.setStyle()
if
(isWidescreen) {
uni.hideTabBar()
}
else {
uni.showTabBar()
}
}
},
},
computed: {
...mapState({
//当前正在对话端用户ID,实现pc端高亮效果
...
...
@@ -111,9 +110,9 @@
...mapGetters({
conversationList: 'uniIm/conversationList',
unread_count: 'uniIm/unread_count'
}),
currentUserInfo()
{
return uniIdStore.userInfo
}),
currentUserInfo()
{
return uniIdStore.userInfo
},
avatarUrl() {
if (this.currentUserInfo.avatar_file && this.currentUserInfo.avatar_file.url) {
...
...
@@ -127,8 +126,7 @@
wHeight: 'auto',
isWidescreen: false,
userInfo: {},
scrollTop: 0,
scrollIntoView: ""
scrollTop: 0
};
},
async onShow() {
...
...
@@ -136,8 +134,7 @@
this.setStyle()
// #endif
},
beforeCreate() {
},
beforeCreate() {},
created() {
// #ifdef H5
const mediaQueryOb = uni.createMediaQueryObserver(this)
...
...
@@ -151,126 +148,134 @@
// #ifdef APP-NVUE
this.wHeight = uni.getSystemInfoSync().windowHeight + 'px'
// #endif
// #ifdef H5
uni.$on('uni-im-showLast', e => {
// console.log('uni-im-showLast');
// this.scrollTop = 100
this.scrollIntoView = ''
this.$nextTick(e => {
this.scrollIntoView = 'last-chat-view'
})
this.scrollTop = document.querySelector('#chat-view .uni-scroll-view-content').scrollHeight
})
// #endif
},
async onLoad({
token,
user_id,
goods,
conversation_id
}) {
// 发布新版本后,清理旧版本下的storage避免脏数据引发问题
let version = '2022.11.11.01'
if(uni.getStorageSync('uni-im-storage-version') != version){
let data = uni.getStorageInfoSync();
console.log('data.keys', JSON.stringify(data.keys));
data.keys.forEach(item => {
if (item.includes('uni-im-msg:') || item.includes('uni-im-conversation')) {
// console.log(item);
uni.removeStorageSync(item);
console.log(uni.getStorageSync(item));
}
});
uni.setStorageSync('uni-im-storage-version',version)
}
}) {
// 发布新版本后,清理旧版本下的storage避免脏数据引发问题
let version = '2022.11.23.01'
if (uni.getStorageSync('uni-im-storage-version') != version) {
let data = uni.getStorageInfoSync();
// console.log('data.keys', JSON.stringify(data.keys));
data.keys.forEach(item => {
if (item.includes('uni-im-msg:') || item.includes('uni-im-conversation')) {
// console.log(item);
uni.removeStorageSync(item);
console.log(uni.getStorageSync(item));
}
});
uni.setStorageSync('uni-im-storage-version',version)
}
if (token) {
// #ifdef H5
//删除地址栏的token,且不刷新页面
history.pushState({},'','/#/');
if (token) {
// #ifdef H5
//删除地址栏的token,且不刷新页面
history.pushState({},'','/#/');
// #endif
//来源三方系统登录的token
//来源三方系统登录的token
const uniImCo = uniCloud.importObject("uni-im-co",{
loadingOptions: {
title: '登录中'
}
})
let res = await uniImCo.login(token)
await uniIdMutations.updateUserInfo()
// return
/*const uniImOpenApi = uniCloud.importObject("uni-im-openapi", {
loadingOptions: {
title: '登录中'
}
})
const loginRes = await uniImOpenApi
.login(token)
let res = await uniImCo
.login(token)
await uniIdMutations.updateUserInfo()
if(loginRes.chattingUserInfo){
user_id = loginRes.chattingUserInfo._id
}*/
} else {
if (!uniCloud.getCurrentUserInfo().uid) {
if (!uniCloud.getCurrentUserInfo().uid) {
return uni.redirectTo({
url: '/uni_modules/uni-id-pages/pages/login/login-withpwd'
})
}
}
}
this.init({
user_id,
goods,
conversation_id
})
// console.log('user_id',user_id);
// 初始化会话列表
await this.loadMore()
if (conversation_id) {
this.toChat(conversation_id)
} else if (user_id) {
//创建会话
const currentConversation = await this.getConversation({
user_id
})
console.log('currentConversation', currentConversation);
// 当前用户给对方发个消息
this.toChat(currentConversation.id)
} else {
if (this.isWidescreen) {
let [firstConversation] = this.conversationList
if (firstConversation) {
setTimeout(() => {
this.toChat(firstConversation.id)
}, 100);
} else {
uni.showModal({
content: '没有任何会话,请先到用户列表选择用户',
showCancel: false
});
}
}
}
if (this.isWidescreen && goods) {
console.log(goods);
if (typeof goods != 'object') {
goods = JSON.parse(goods)
}
const {
name,
url
} = goods
if (name && url) {
this.$refs['chat-view'].chatText = '【' + name + ':' + url + '】'
}
}
uni.$on('uni-id-pages-login-success', async () => {
this.init({
user_id,
goods,
conversation_id
})
})
},
onUnload() {
uni.$off('uni-id-pages-login-success')
},
onHide() {},
methods: {
...mapMutations({
...mapMutations({
setCurrentConversationId: 'uniIm/setCurrentConversationId',
updateConversation: 'uniIm/updateConversation'
}),
...mapActions({
// 加载更多会话数据
loadMore: 'uniIm/loadMoreConversation',
initConversationData: 'uniIm/initConversationData',
getConversation: 'uniIm/getConversation',
setMsgList: 'uniIm/setMsgList'
}),
async init({
conversation_id,
user_id,
goods
}) {
// 初始化会话列表
await this.initConversationData()
if (conversation_id) {
console.log('conversation_id', conversation_id);
this.toChat(conversation_id)
} else if (user_id) {
//创建会话
const currentConversation = await this.getConversation({
user_id
})
console.log('currentConversation', currentConversation);
// 当前用户给对方发个消息
this.toChat(currentConversation.id)
} else {
if (this.isWidescreen) {
let [firstConversation] = this.conversationList
if (firstConversation) {
setTimeout(() => {
this.toChat(firstConversation.id)
}, 100);
} else {
uni.showModal({
content: '没有任何会话,请先到用户列表选择用户',
showCancel: false
});
}
}
}
if (this.isWidescreen && goods) {
console.log(goods);
if (typeof goods != 'object') {
goods = JSON.parse(goods)
}
const {
name,
url
} = goods
if (name && url) {
this.$refs['chat-view'].chatText = '【' + name + ':' + url + '】'
}
}
},
search(e) {
// console.log("search-e: " + JSON.stringify(e));
uni.showToast({
...
...
@@ -279,8 +284,8 @@
});
},
onScroll(e) {
if (this.isWidescreen) {
// console.log('--------------onPageScroll',e, e.detail.scrollTop);
if (this.isWidescreen) {
// console.log('--------------onPageScroll',e, e.detail.scrollTop);
setTimeout(() => {
if (this.scrollTop == e.detail.scrollTop && this.scrollTop < 50) {
// console.log('滚动结束', e.detail.scrollTop);
...
...
@@ -302,14 +307,16 @@
});
},
toChat(conversation_id) {
// console.log('toChat',{conversation_id,'isWidescreen':this.isWidescreen});
// console.log('toChat',{conversation_id,'isWidescreen':this.isWidescreen});
this.setCurrentConversationId(conversation_id);
if (this.isWidescreen) { //若为宽屏,则触发右侧详情页的自定义事件,通知右侧窗体刷新详情
this.$refs['chat-view'].load(conversation_id)
if(this.$refs['chat-view']){
this.$refs['chat-view'].load(conversation_id)
}
} else { // 若为窄屏,则打开新窗体,在新窗体打开详情页面
uni.navigateTo({
url: '/uni_modules/uni-im/pages/chat/chat?conversation_id=' + conversation_id,
animationDuration:
300
url: '/uni_modules/uni-im/pages/chat/chat?conversation_id=' + conversation_id,
animationDuration:
300
})
}
},
...
...
@@ -324,12 +331,13 @@
formatTime(timestamp) {
return uniImUtils.formatTime(timestamp)
},
setStyle() {
setStyle() {
// #ifdef H5
/* 删除页面的占位元素 */
let conversationChildDom = document.querySelector('uni-page[data-page="uni_modules/uni-im/pages/index/index"]')
if(!conversationChildDom){
return
/* 删除页面的占位元素 */
let conversationChildDom = document.querySelector(
'uni-page[data-page="uni_modules/uni-im/pages/index/index"]')
if (!conversationChildDom) {
return
}
let conversationDom = conversationChildDom.parentElement
if (!conversationDom) {
...
...
@@ -352,31 +360,34 @@
}
// #endif
}
},
onNavigationBarButtonTap(e) {
console.log(e);
if (e.index) {
let data = uni.getStorageInfoSync();
console.log('data.keys', JSON.stringify(data.keys));
data.keys.forEach(item => {
if (item.includes('uni-im-msg:') || item.includes('uni-im-conversation')) {
// console.log(item);
uni.removeStorageSync(item);
console.log(uni.getStorageSync(item));
}
});
uni.showToast({
title: 'clear storage ok',
icon: 'none'
});
} else {
uni.navigateTo({
url: '/uni_modules/uni-id-pages/pages/login/login-withpwd',
complete: e => {
console.log(e);
}
});
}
},
async onReachBottom() {
await this.loadMore()
},
onNavigationBarButtonTap(e) {
console.log(e);
if (e.index) {
let data = uni.getStorageInfoSync();
console.log('data.keys', JSON.stringify(data.keys));
data.keys.forEach(item => {
if (item.includes('uni-im-msg:') || item.includes('uni-im-conversation')) {
// console.log(item);
uni.removeStorageSync(item);
console.log(uni.getStorageSync(item));
}
});
uni.showToast({
title: 'clear storage ok',
icon: 'none'
});
} else {
uni.navigateTo({
url: '/uni_modules/uni-id-pages/pages/login/login-withpwd',
complete: e => {
console.log(e);
}
});
}
},
}
</script>
...
...
@@ -386,8 +397,8 @@
#page,
view {
display: flex;
flex-direction: row;
}
flex-direction: row;
}
view,
scroll-view {
...
...
@@ -404,17 +415,19 @@
border-right: solid 1px #dededd;
}
#user-list-box {
height: calc(100vh -
4
4px);
#user-list-box {
height: calc(100vh -
9
4px);
}
@media screen and (min-width: 960px) {
#page,page {
background-color: #2e2e3e;
}
#user-list-box {
width: 299px;
#page,
page {
background-color: #2e2e3e;
}
#user-list-box {
width: 299px;
}
#left-tabbar {
...
...
@@ -445,7 +458,7 @@
}
#user-list-box .user-list {
width: 100% !important;
width: 100% !important;
}
#chat-view-box {
...
...
@@ -474,9 +487,10 @@
/* #ifndef APP-NVUE */
scroll-anchoring: 'auto'
/* #endif */
}
#chat-view ::v-deep .null{
background-color: #f8f8f8;
}
#chat-view ::v-deep .null {
background-color: #f8f8f8;
}
#chat-view ::v-deep #list {
...
...
@@ -488,8 +502,8 @@
}
// pc端不用占位符,因为头部是虚拟的
#chat-view ::v-deep .msg-list-box {
margin-top: 0;
#chat-view ::v-deep .msg-list-box {
margin-top: 0;
}
#chat-view ::v-deep .page * {
...
...
@@ -520,14 +534,20 @@
#conversation ::v-deep .uni-list--border,
#conversation ::v-deep .uni-list--border-top {
display: none;
}
/* #ifdef VUE3 && H5 */
::v-deep{
.formatTime,.msg-list, .msg-box,.loadMore,.tip-view{
width: 660px;
}
}
}
/* #ifdef VUE3 && H5 */
::v-deep {
.formatTime,
.msg-list,
.msg-box,
.loadMore,
.tip-view {
width: 660px;
}
}
/* #endif */
}
...
...
@@ -604,8 +624,8 @@
left: calc(50% - 130px);
width: 260px;
text-align: center;
z-index: 999;
z-index: 999;
}
/* #endif */
</style>
\ No newline at end of file
/* #endif */
</style>
uni_modules/uni-im/pages_init.json
浏览文件 @
ce2ad049
...
...
@@ -12,7 +12,7 @@
{
"path"
:
"uni_modules/uni-im/pages/chat/chat"
,
"style"
:
{
"navigationBarTitleText"
:
"
会话列表
"
,
"navigationBarTitleText"
:
""
,
"enablePullDownRefresh"
:
false
,
"maxWidth"
:
"960"
}
...
...
uni_modules/uni-im/readme.md
浏览文件 @
ce2ad049
**APP端兼容性说明**
:仅支持Vue2,且HBuilderX的版本为3.6.9+,否则chat页面存在滚动锚定问题(后续会修复此问题)
<h2>
文档已移至
<a
href=
"https://uniapp.dcloud.io/uniCloud/uni-im.html"
target=
"_blank"
>
uni-im文档
</a>
</h2>
...
...
uni_modules/uni-im/uniCloud/cloudfunctions/uni-im-co/index.obj.js
浏览文件 @
ce2ad049
// 云对象教程: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj
// jsdoc语法提示教程:https://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/129
const
admin_user_id
=
false
//['63413736d76aaf000137e890']
const
db
=
uniCloud
.
database
();
const
conversationTable
=
db
.
collection
(
'
uni-im-conversation
'
)
const
msgTable
=
db
.
collection
(
'
uni-im-msg
'
)
...
...
@@ -10,7 +9,10 @@ const dbCmd = db.command
const
$
=
dbCmd
.
aggregate
const
md5
=
require
(
"
md5
"
);
const
jwt
=
require
(
"
jsonwebtoken
"
);
const
createConfig
=
require
(
"
uni-config-center
"
);
const
createConfig
=
require
(
"
uni-config-center
"
);
const
uniImConfig
=
createConfig
({
pluginId
:
'
uni-im
'
,
// 插件id
})
module
.
exports
=
{
_before
()
{
this
.
clientInfo
=
this
.
getClientInfo
()
...
...
@@ -29,7 +31,7 @@ module.exports = {
}
res
=
await
conversationTable
.
aggregate
()
.
sort
({
update_time
:
1
update_time
:
-
1
})
.
match
({
"
owner_uid
"
:
res
.
uid
,
...
...
@@ -111,19 +113,23 @@ module.exports = {
}
//发送者身份id
const
from_uid
=
res
.
uid
if
(
admin_user_id
&&
!
(
admin_user_id
.
includes
(
from_uid
)
||
admin_user_id
.
includes
(
to_uid
))
){
return
{
errMsg
:
'
非法通讯,会话双方用户id,均不属于uni-im-co中配置的admin_user_id
'
,
errSubject
:
"
uni-im
"
,
errCode
:
40001
}
let
admin_uid
=
uniImConfig
.
config
(
'
admin_uid
'
)
if
(
admin_uid
){
if
(
typeof
admin_uid
==
'
string
'
){
admin_uid
=
[
admin_uid
]
}
if
(
!
(
admin_uid
.
includes
(
from_uid
)
||
admin_uid
.
includes
(
to_uid
))
){
return
{
errMsg
:
'
非法通讯,会话双方用户id,均不属于uni-im-co中配置的admin_uid
'
,
errSubject
:
"
uni-im
"
,
errCode
:
40001
}
}
}
const
conversation_id
=
getConversationId
([
from_uid
,
to_uid
])
const
msgData
=
{
body
,
...
...
@@ -249,11 +255,14 @@ module.exports = {
let
uniPush
=
uniCloud
.
getPushManager
({
appId
:
params
.
appId
})
res
=
await
uniPush
.
sendMessage
(
param
)
if
(
res
.
errCode
)
{
// if(res.errCode == "uni-push-user-invalid"){
// //可能因为用户长时间没有登录导致的cid过期而发送失败,但是此时已将离线数据写入数据库,登录后可获取。客户端不需要进入 catch
// }
res
=
{
cause
:
res
if
(
res
.
errCode
==
"
uni-push-user-invalid
"
){
//可能因为用户长时间没有登录导致的cid过期而发送失败,但是此时已将离线数据写入数据库,登录后可获取。客户端不需要进入 catch
res
=
{
cause
:
res
,
errCode
:
0
}
}
else
{
return
res
}
}
console
.
log
(
'
sendMessage
'
,
JSON
.
stringify
(
res
))
...
...
@@ -269,17 +278,26 @@ module.exports = {
}
}
console.log('state : ============> ' + state);*/
res
.
data
.
create_time
=
msgData
.
create_time
return
res
if
(
!
res
.
data
){
res
.
data
=
{}
}
res
.
data
.
create_time
=
msgData
.
create_time
return
res
},
async
loginWithJWT
(
sign
){
const
uniImConfig
=
createConfig
({
pluginId
:
'
uni-im
'
,
// 插件id
})
let
jwtSecret
=
uniImConfig
.
config
(
'
jwtSecret
'
)
if
(
jwtSecret
==
'
jwtSecretDemo
'
){
console
.
error
(
'
[warn]: 不要使用默认的:jwtSecret的值
'
);
let
jwtSecret
=
uniImConfig
.
config
(
'
jwtSecret
'
)
if
(
!
jwtSecret
){
return
{
errCode
:
4000
,
errMsg
:
'
jwtSecret的值不能为空
'
}
}
if
(
jwtSecret
==
'
jwtSecretDemo
'
){
console
.
error
(
'
[warn]: 不要使用默认的:jwtSecret的值
'
);
return
{
errCode
:
4100
,
errMsg
:
'
不要使用默认的:jwtSecret的值
'
}
}
let
userInfo
;
try
{
let
decoded
=
jwt
.
verify
(
sign
,
jwtSecret
);
...
...
@@ -319,7 +337,7 @@ module.exports = {
errCode
:
0
,
newToken
}
}
}
}
function
getConversationId
(
param
)
{
...
...
uni_modules/uni-list/changelog.md
浏览文件 @
ce2ad049
## 1.2.10(2022-11-23)
修复 uni-list-item 组件 keep-scroll-position 属性 无法设置为false的错误
## 1.2.9(2022-11-22)
-
修复 uni-list-chat 在vue3下跳转报错的bug
## 1.2.8(2022-11-21)
-
修复 uni-list-chat avatar属性 值为本地路径时错误的问题
## 1.2.7(2022-11-21)
-
修复 uni-list-chat avatar属性 在腾讯云版uniCloud下错误的问题
## 1.2.6(2022-11-18)
-
修复 uni-list-chat note属性 支持:“草稿”字样功能 文本少1位的问题
## 1.2.5(2022-11-15)
-
修复 uni-list-item 的 customStyle 属性 padding值在 H5端 无效的bug
## 1.2.4(2022-11-15)
...
...
uni_modules/uni-list/components/uni-list-chat/uni-list-chat.vue
浏览文件 @
ce2ad049
...
...
@@ -26,7 +26,7 @@
<text
class=
"uni-list-chat__content-title uni-ellipsis"
>
{{
title
}}
</text>
<view
style=
"flex-direction: row;"
>
<text
class=
"draft"
v-if=
"isDraft"
>
[草稿]
</text>
<text
class=
"uni-list-chat__content-note uni-ellipsis"
>
{{
isDraft
?
note
.
slice
(
14
,
-
1
):
note
}}
</text>
<text
class=
"uni-list-chat__content-note uni-ellipsis"
>
{{
isDraft
?
note
.
slice
(
14
):
note
}}
</text>
</view>
</view>
<view
class=
"uni-list-chat__content-extra"
>
...
...
@@ -155,7 +155,7 @@
watch
:
{
avatar
:{
handler
(
avatar
)
{
if
(
avatar
.
includes
(
'
://
'
)
){
if
(
avatar
.
substr
(
0
,
8
)
==
'
cloud://
'
){
uniCloud
.
getTempFileURL
({
fileList
:
[
avatar
]
}).
then
(
res
=>
{
...
...
uni_modules/uni-list/components/uni-list-item/uni-list-item.vue
浏览文件 @
ce2ad049
<
template
>
<!-- #ifdef APP-NVUE -->
<cell
keep-scroll-position
>
<cell
:keep-scroll-position=
"keepScrollPosition"
>
<!-- #endif -->
<view
:class=
"
{ 'uni-list-item--disabled': disabled }" :style="{'background-color':customStyle.backgroundColor}"
:hover-class="(!clickable
&&
!link) || disabled || showSwitch ? '' : 'uni-list-item--hover'"
...
...
@@ -183,6 +183,10 @@
backgroundColor
:
'
#FFFFFF
'
}
}
},
keepScrollPosition
:
{
type
:
Boolean
,
default
:
false
}
},
watch
:
{
...
...
uni_modules/uni-list/package.json
浏览文件 @
ce2ad049
{
"id"
:
"uni-list"
,
"displayName"
:
"uni-list 列表"
,
"version"
:
"1.2.
5
"
,
"version"
:
"1.2.
10
"
,
"description"
:
"List 组件 ,帮助使用者快速构建列表。"
,
"keywords"
:
[
""
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录