Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
hello uni-im
提交
d6e6c02d
H
hello uni-im
项目概览
DCloud
/
hello uni-im
通知
2543
Star
37
Fork
16
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
4
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
H
hello uni-im
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
4
Issue
4
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
d6e6c02d
编写于
9月 05, 2024
作者:
DCloud_JSON
提交者:
DCloud_JSON
11月 06, 2024
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
更新 uni-im-msg-reader 为 1.0.2
上级
c4007b41
变更
6
显示空白变更内容
内联
并排
Showing
6 changed file
with
313 addition
and
224 deletion
+313
-224
uni_modules/uni-im-msg-reader/changelog.md
uni_modules/uni-im-msg-reader/changelog.md
+4
-0
uni_modules/uni-im-msg-reader/components/uni-im-msg-reader/uni-im-msg-reader.vue
...reader/components/uni-im-msg-reader/uni-im-msg-reader.vue
+229
-204
uni_modules/uni-im-msg-reader/extension.js
uni_modules/uni-im-msg-reader/extension.js
+32
-10
uni_modules/uni-im-msg-reader/package.json
uni_modules/uni-im-msg-reader/package.json
+9
-9
uni_modules/uni-im-msg-reader/pages/reader-list/reader-list.vue
...dules/uni-im-msg-reader/pages/reader-list/reader-list.vue
+38
-0
uni_modules/uni-im-msg-reader/uniCloud/cloudfunctions/common/uni-im-ext-msg-reader/package.json
.../cloudfunctions/common/uni-im-ext-msg-reader/package.json
+1
-1
未找到文件。
uni_modules/uni-im-msg-reader/changelog.md
浏览文件 @
d6e6c02d
## 1.0.0(2024-05-06)
第一版
## 1.0.1(2024-06-21)
更新:在移动端点击未读详情时,以独立页面展示
## 1.0.2(2024-11-06)
更新:兼容 uni-im 3.4.x
\ No newline at end of file
uni_modules/uni-im-msg-reader/components/uni-im-msg-reader/uni-im-msg-reader.vue
浏览文件 @
d6e6c02d
<
template
>
<view
v-if=
"!msg.is_revoke"
:class=
"
{'self':currentUid == msg.from_uid}
">
<view
v-if=
"!msg.is_revoke && !msg.revoke_ing"
:class=
"
{'self':currentUid == msg.from_uid}" class="uni-im-msg-reader
">
<text
v-if=
"readerList
"
v-if=
"readerList && !hiddenState
"
class=
"read-state"
:class=
"
{'active-color':isGroupMsg
&&
unreadUserList.length
}"
@click="showReaderList
"
:class=
"
{'active-color':unreadUserList.length || readerList.length,isGroupMsg
}"
@click="clickHandler
"
>
{{
isGroupMsg
?
unreadUserCountTip
:
(
readerList
.
length
?
'
已读
'
:
'
未读
'
)
}}
{{
isGroupMsg
?
(
isReady
?
unreadUserCountTip
:
''
)
:
(
readerList
.
length
?
'
已读
'
:
'
未读
'
)
}}
</text>
<!-- #ifdef H5 -->
<teleport
to=
"body"
:disabled=
"!isWidescreen"
>
<!-- #endif -->
<view
v-if=
"showPopup && isGroupMsg"
class=
"
popup"
class=
"uni-im-msg-reader-
popup"
@
click=
"closePopup"
>
<view
...
...
@@ -20,10 +23,10 @@
@click.stop
>
<text
class=
"title"
>
消息接收人列表
</text>
<uni-segmented-control
<uni-segmented-control
class=
"segmented-control"
v-if=
"!isWidescreen"
:current=
"currentIndex"
:values=
"[`未读($
{memberUids.length - read
erList.length})`, `已读(${readerList.length})`]"
:values=
"[`未读($
{unreadUs
erList.length})`, `已读(${readerList.length})`]"
style-type="text"
active-color="black"
@clickItem="e => currentIndex = e.currentIndex"
...
...
@@ -31,7 +34,7 @@
<view
class=
"content"
>
<view
v-if=
"isWidescreen || currentIndex == 0"
class=
"reader-list"
>
<text
v-if=
"isWidescreen"
class=
"title"
>
{{
memberUids
.
length
-
read
erList
.
length
}}
人未读
{{
unreadUs
erList
.
length
}}
人未读
</text>
<scroll-view
class=
"user-list"
scroll-y
>
<view
...
...
@@ -78,7 +81,10 @@
</view>
</view>
</view>
</view>
<!-- #ifdef H5 -->
</teleport>
<!-- #endif -->
</view>
</
template
>
<
script
>
...
...
@@ -92,6 +98,10 @@ export default {
msg
:
{
type
:
Object
,
default
:
()
=>
{}
},
hiddenState
:
{
type
:
Boolean
,
default
:
false
}
},
data
()
{
...
...
@@ -99,26 +109,34 @@ export default {
showPopup
:
false
,
showTransition
:
false
,
conversation
:
{},
currentIndex
:
0
,
currentIndex
:
0
}
},
// 计算属性
computed
:
{
...
uniIm
.
mapState
([
'
isWidescreen
'
,
'
systemInfo
'
]),
currentUid
()
{
return
uniCloud
.
getCurrentUserInfo
().
uid
return
uniIm
.
currentUser
.
_id
},
isReady
()
{
// 群会话需要等待群成员数据,全部加载完毕
return
!
this
.
conversation
.
group
?.
member
?.
hasMore
},
memberUids
()
{
const
groupMember
=
this
.
conversation
&&
this
.
conversation
.
group_member
||
{}
const
groupMember
=
this
.
conversation
.
group
?.
member
if
(
groupMember
){
// 成员uid不包含消息发送者
return
Object
.
keys
(
groupMember
).
filter
(
uid
=>
uid
!=
this
.
msg
.
from_uid
)
return
groupMember
.
dataList
.
filter
(
item
=>
item
.
users
.
_id
!=
this
.
msg
.
from_uid
).
map
(
item
=>
item
.
users
.
_id
)
}
else
{
return
[]
}
},
unreadUserList
()
{
const
unreadUserList
=
this
.
memberUids
.
filter
(
item
=>
!
this
.
readerList
.
find
(
reader
=>
reader
.
user_id
==
item
))
return
unreadUserList
.
map
(
item
=>
uniIm
.
users
[
item
])
},
unreadUserCountTip
()
{
let
unreadUserCount
=
this
.
memberUids
.
length
-
this
.
read
erList
.
length
let
unreadUserCount
=
this
.
unreadUs
erList
.
length
// 大于99人显示99+
unreadUserCount
=
unreadUserCount
>
99
?
'
99+
'
:
unreadUserCount
return
unreadUserCount
>
0
?
`
${
unreadUserCount
}
人未读`
:
'
全部已读
'
...
...
@@ -141,14 +159,25 @@ export default {
}
},
mounted
()
{
this
.
conversation
=
uniIm
.
conversation
.
dataList
.
find
(
conversation
=>
conversation
.
id
==
this
.
msg
.
conversation_id
)
this
.
conversation
=
uniIm
.
conversation
.
find
(
this
.
msg
.
conversation_id
)
},
methods
:
{
clickHandler
()
{
if
(
this
.
isGroupMsg
){
if
(
uniIm
.
isWidescreen
){
this
.
showReaderList
()
}
else
{
uni
.
navigateTo
({
url
:
`/uni_modules/uni-im-msg-reader/pages/reader-list/reader-list?msgId=
${
this
.
msg
.
_id
}
&conversationId=
${
this
.
msg
.
conversation_id
}
`
,
// animationType: 'slide-in-bottom'
})
}
}
},
showReaderList
()
{
if
(
this
.
isGroupMsg
)
{
// this.$refs.popup.open()
this
.
showPopup
=
true
}
// this.$refs.popup.open()
},
closePopup
()
{
this
.
showPopup
=
false
...
...
@@ -157,106 +186,67 @@ export default {
}
</
script
>
<
style
lang=
"scss"
scoped
>
.self
{
align-items
:
flex-end
;
}
<
style
lang=
"scss"
>
.uni-im-msg-reader
{
display
:
flex
;
width
:
100%
;
flex
:
1
;
overflow
:
hidden
;
.read-state
{
font-size
:
12px
;
flex-direction
:
row
;
color
:
#999
;
color
:
#555
;
margin
:
0
60px
;
width
:
65px
;
height
:
16px
;
}
.self
.read-state
{
text-align
:
right
;
}
.active-color
{
color
:
#0b65ff
;
}
color
:
#aaa
;
&
.isGroupMsg
{
/* #ifdef H5 */
.active-color
{
cursor
:
pointer
;
}
/* #endif */
.reader-list-box
{
background-color
:
#fff
;
border-radius
:
10px
;
overflow
:
hidden
;
/* 显示隐藏的过度动画 */
transition
:
transform
0
.1s
,
opacity
0
.1s
;
transform
:
scale
(
0
.7
);
opacity
:
0
;
color
:
#0b65ff
;
}
.show
{
transform
:
scale
(
1
);
opacity
:
1
;
}
.reader-list-box
>
.title
{
font-size
:
18px
;
font-weight
:
bold
;
color
:
#333
;
padding
:
10px
;
background-color
:
#f5f5f5
;
&
.self
{
align-items
:
flex-end
;
.read-state
{
text-align
:
right
;
}
.reader-list-box
.content
{
flex-direction
:
row
;
padding
:
10px
;
width
:
550rpx
;
}
.reader-list
{
flex-direction
:
column
;
padding
:
0
10px
;
flex
:
1
;
/* #ifndef APP-NVUE */
width
:
50%
;
min-width
:
260px
;
max-height
:
80vh
!
important
;
/* #endif */
}
.reader-list
.title
{
font-size
:
16px
;
font-weight
:
bold
;
color
:
#333
;
margin-bottom
:
10px
;
.uni-im-msg-reader-popup
{
height
:
100%
;
.reader-list-box
{
width
:
750rpx
;
height
:
100%
;
.segmented-control
{
flex-shrink
:
0
;
}
.reader-list
.user-list
{
height
:
750rpx
;
&
>
.title
{
display
:
none
;
}
/* #ifdef H5 */
@media
screen
and
(
min-device-width
:
960px
)
{
.reader-list
:last-child
{
border-left
:
1px
solid
#eee
;
.content
{
height
:
100%
;
overflow
:
hidden
;
.reader-list
{
flex-direction
:
column
;
overflow
:
hidden
;
.title
{
padding
:
15px
;
background-color
:
#FFF
;
font-size
:
20px
;
}
.reader-list
.user-list
{
.user-list
{
flex
:
1
;
}
.reader-list-box
.content
{
width
:
auto
;
}
}
/* #endif */
.reader-list
.users
{
overflow
:
hidden
;
.users
{
flex-direction
:
row
;
align-items
:
center
;
margin-bottom
:
10px
;
}
.reader-list
.users
:last-child
{
margin-bottom
:
0
;
}
.reader-list
.users
.nickname
{
padding
:
10px
;
.nickname
{
font-size
:
16px
;
color
:
#333
;
margin-left
:
6px
;
...
...
@@ -267,23 +257,58 @@ export default {
white-space
:
nowrap
;
/* #endif */
}
.popup
{
position
:
fixed
;
}
}
}
}
}
}
/* #ifdef H5 */
@media
screen
and
(
min-device-width
:
960px
)
{
.uni-im-msg-reader-popup
{
position
:
fixed
!
important
;
top
:
0
;
left
:
0
;
/* #ifdef APP-NVUE */
width
:
750rpx
;
bottom
:
0
;
/* #endif */
/* #ifndef APP-NVUE */
z-index
:
9999
;
width
:
100%
;
height
:
100%
;
/* #endif */
background-color
:
rgba
(
0
,
0
,
0
,
0
.3
);
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
align-items
:
center
!
important
;
.reader-list-box
{
background-color
:
#fff
;
border-radius
:
10px
;
overflow
:
hidden
;
/* 显示隐藏的过度动画 */
transition
:
transform
0
.1s
,
opacity
0
.1s
;
transform
:
scale
(
0
.7
);
opacity
:
0
;
width
:
600px
;
margin-top
:
44px
;
height
:
50%
;
flex-direction
:
column
;
&
.show
{
transform
:
scale
(
1
);
opacity
:
1
;
}
&
>
.title
{
display
:
flex
;
font-size
:
18px
;
font-weight
:
bold
;
color
:
#333
;
padding
:
15px
;
background-color
:
#f5f5f5
;
}
.content
{
flex-direction
:
row
;
padding
:
5px
15px
;
.reader-list
{
flex
:
1
;
}
}
}
}
}
/* #endif */
</
style
>
\ No newline at end of file
uni_modules/uni-im-msg-reader/extension.js
浏览文件 @
d6e6c02d
import
uniIm
from
'
@/uni_modules/uni-im/sdk/index.js
'
import
UniImMsgReader
from
'
@/uni_modules/uni-im-msg-reader/components/uni-im-msg-reader/uni-im-msg-reader.vue
'
function
install
()
{
// 配置在什么情况下启用已读功能
uniIm
.
extensions
.
installExt
(
'
msg-extra
'
,
(
msg
,
currentUser
)
=>
{
// 仅限“我”发送的消息
if
(
msg
.
from_uid
!==
uniIm
.
currentUser
.
_id
)
return
// 仅限内部用户
if
(
!
uniIm
.
currentUser
.
role
.
includes
(
'
staff
'
))
return
// 排除特殊消息
if
(
msg
.
type
==
'
system
'
||
msg
.
is_revoke
)
return
// 仅限私聊会话
let
conversation
=
uniIm
.
conversation
.
find
(
msg
.
conversation_id
)
if
(
!
conversation
?.
friend_uid
)
return
return
{
component
:
UniImMsgReader
,
props
:
{
msg
}
}
})
// 注册 read_msg 消息类型
uniIm
.
extensions
.
installExt
(
'
msg-type-register
'
,
()
=>
{
return
{
...
...
@@ -18,38 +39,39 @@ function install() {
from_uid
,
create_time
,
}
=
msgData
const
msg
=
conversation
.
msgList
.
find
(
msg
=>
msg
.
_id
===
msgId
)
// debugger
const
msg
=
conversation
.
msg
.
find
(
msgId
)
if
(
msg
)
{
let
reader
=
{
user_id
:
from_uid
,
create_time
}
msg
.
reader_list
?
msg
.
reader_list
.
push
(
reader
)
:
msg
.
reader_list
=
[
reader
]
conversation
.
msgManager
.
localMsg
.
update
(
msg
.
unique_id
,
msg
)
}
},
}
})
// 监听每条消息的显示状态,报送 read_msg 消息
uniIm
.
extensions
.
installExt
(
'
msg-appear
'
,
(
msg
,
currentUser
)
=>
{
uniIm
.
extensions
.
installExt
(
'
msg-appear
'
,
msg
=>
{
const
currentUid
=
uniIm
.
currentUser
.
_id
// 特殊消息不用处理
if
(
msg
.
type
===
'
system
'
||
msg
.
is_revoke
)
return
// 如果是我发送的消息则不处理
if
(
msg
.
from_uid
==
currentU
ser
.
user_
id
)
return
if
(
msg
.
from_uid
==
currentUid
)
return
// 如果我已经在已读列表里则不再处理
if
(
msg
.
reader_list
?.
some
(
u
=>
u
.
user_id
==
currentU
ser
.
user_
id
))
return
if
(
msg
.
reader_list
?.
some
(
u
=>
u
.
user_id
==
currentUid
))
return
// 如果是群聊消息且没有 @我,则不用处理
let
conversation
=
uniIm
.
conversation
.
getCache
d
(
msg
.
conversation_id
)
if
(
conversation
.
group_id
&&
!
msg
.
call_uid
?.
includes
(
currentU
ser
.
user_
id
))
return
let
conversation
=
uniIm
.
conversation
.
fin
d
(
msg
.
conversation_id
)
if
(
conversation
.
group_id
&&
!
msg
.
call_uid
?.
includes
(
currentUid
))
return
// 把自己记入已读列表
msg
.
reader_list
=
msg
.
reader_list
||
[]
msg
.
reader_list
.
push
({
user_id
:
currentU
ser
.
user_
id
,
user_id
:
currentUid
,
create_time
:
Date
.
now
()
})
...
...
@@ -64,7 +86,7 @@ function install() {
}
}).
catch
(
e
=>
{
// 提交失败,把自己从已读列表里去掉
msg
.
reader_list
=
msg
.
reader_list
.
filter
(
u
=>
u
.
user_id
!==
currentU
ser
.
user_
id
)
msg
.
reader_list
=
msg
.
reader_list
.
filter
(
u
=>
u
.
user_id
!==
currentUid
)
})
})
}
...
...
uni_modules/uni-im-msg-reader/package.json
浏览文件 @
d6e6c02d
{
"id"
:
"uni-im-msg-reader"
,
"displayName"
:
"uni-im-msg-reader"
,
"version"
:
"1.0.
0
"
,
"version"
:
"1.0.
2
"
,
"description"
:
"uni-im的消息已读未读状态展示插件"
,
"keywords"
:
[
"uni-im-msg-reader"
],
"repository"
:
""
,
"engines"
:
{
"HBuilderX"
:
"^4.
14
"
"HBuilderX"
:
"^4.
29
"
},
"dcloudext"
:
{
"type"
:
"component-vue"
,
...
...
@@ -25,7 +25,7 @@
},
"declaration"
:
{
"ads"
:
"无"
,
"data"
:
"
插件不采集任何数据
"
,
"data"
:
"
无
"
,
"permissions"
:
"无"
},
"npmurl"
:
""
...
...
@@ -46,17 +46,17 @@
},
"App"
:
{
"app-vue"
:
"y"
,
"app-nvue"
:
"
y
"
,
"app-nvue"
:
"
n
"
,
"app-uvue"
:
"n"
},
"H5-mobile"
:
{
"Safari"
:
"
n
"
,
"Android Browser"
:
"
n
"
,
"微信浏览器(Android)"
:
"
n
"
,
"QQ浏览器(Android)"
:
"
n
"
"Safari"
:
"
y
"
,
"Android Browser"
:
"
y
"
,
"微信浏览器(Android)"
:
"
y
"
,
"QQ浏览器(Android)"
:
"
y
"
},
"H5-pc"
:
{
"Chrome"
:
"
n
"
,
"Chrome"
:
"
y
"
,
"IE"
:
"n"
,
"Edge"
:
"n"
,
"Firefox"
:
"n"
,
...
...
uni_modules/uni-im-msg-reader/pages/reader-list/reader-list.vue
0 → 100644
浏览文件 @
d6e6c02d
<
template
>
<view
class=
"reader-list-page"
>
<uni-im-msg-reader
ref=
"msg-reader"
:msg=
"msg"
:hiddenState=
"true"
></uni-im-msg-reader>
</view>
</
template
>
<
script
>
import
uniIm
from
'
@/uni_modules/uni-im/sdk/index.js
'
;
export
default
{
data
()
{
return
{
msg
:
{}
}
},
onLoad
(
param
)
{
// console.log('onload', param);
this
.
msg
=
uniIm
.
conversation
.
find
(
param
.
conversationId
).
msg
.
find
(
param
.
msgId
)
this
.
$nextTick
(()
=>
{
const
msgReader
=
this
.
$refs
[
'
msg-reader
'
]
msgReader
.
readStateCanShow
=
false
;
msgReader
.
showReaderList
();
if
(
msgReader
.
unreadUserList
.
length
===
0
){
msgReader
.
currentIndex
=
1
}
});
},
methods
:
{
}
}
</
script
>
<
style
lang=
"scss"
>
@import
"@/uni_modules/uni-im/common/baseStyle.scss"
;
page
,
.reader-list-page
{
width
:
100%
;
height
:
100%
;
}
</
style
>
uni_modules/uni-im-msg-reader/uniCloud/cloudfunctions/common/uni-im-ext-msg-reader/package.json
浏览文件 @
d6e6c02d
{
"name"
:
"uni-im-ext-msg-reader"
,
"version"
:
"1.0.
0
"
,
"version"
:
"1.0.
2
"
,
"description"
:
""
,
"main"
:
"index.js"
,
"keywords"
:
[],
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录