This commit is contained in:
唐明明
2022-02-23 16:50:26 +08:00
30 changed files with 777 additions and 513 deletions

View File

@@ -7,12 +7,12 @@
export default { export default {
onLaunch: function() { onLaunch: function() {
im.initIm('lmxuhwaglu76d') im.initIm('lmxuhwaglu76d')
// return return
//#ifdef APP-PLUS //#ifdef APP-PLUS
// 获取系统版本号 // 获取系统版本号
getVersions({ getVersions({
platform: plus.os.name, platform: plus.os.name,
version: plus.runtime.versionCode version: plus.runtime.version
}).then(res => { }).then(res => {
if (res.update) { if (res.update) {
uni.showModal({ uni.showModal({

View File

@@ -2,8 +2,8 @@
"name" : "ZH-HEALTH", "name" : "ZH-HEALTH",
"appid" : "__UNI__C29473D", "appid" : "__UNI__C29473D",
"description" : "ZH-HEALTH您手上的健康管理专家", "description" : "ZH-HEALTH您手上的健康管理专家",
"versionName" : "1.0.2", "versionName" : "1.0.15",
"versionCode" : 112, "versionCode" : 113,
"transformPx" : false, "transformPx" : false,
/* 5+App */ /* 5+App */
"app-plus" : { "app-plus" : {

View File

@@ -70,7 +70,9 @@
clearMessages() { clearMessages() {
RongIMLib.deleteMessages(RongIMLib.ConversationType.SYSTEM, this.message.sourceUserId) RongIMLib.deleteMessages(RongIMLib.ConversationType.SYSTEM, this.message.sourceUserId)
this.$emit('success') this.$emit('success')
uni.$emit('onContactNotification') uni.$emit('onNewContactConversation', message)
uni.$emit('onNewContactFriends', message)
uni.$emit('onNewContactPendings', message)
} }
} }
} }

View File

@@ -55,7 +55,7 @@
users: [], users: [],
isOwner: false, isOwner: false,
isAdmin: false, isAdmin: false,
canInvite:false,// 是否可以开启邀请 canInvite: false, // 是否可以开启邀请
adminUid: 0, adminUid: 0,
members: 0, members: 0,
actionShow: false, actionShow: false,
@@ -83,7 +83,6 @@
mounted() { mounted() {
this.initGroupInfo() this.initGroupInfo()
getGroupUsers(this.targetId, this.count).then(res => { getGroupUsers(this.targetId, this.count).then(res => {
console.log("res..",res)
this.users = res this.users = res
res.map(item => { res.map(item => {
this.$store.dispatch('updateContact', item) this.$store.dispatch('updateContact', item)

View File

@@ -6,8 +6,10 @@
</view> </view>
<view class="content"> <view class="content">
<view class="header"> <view class="header">
<view class="name">{{ contact(item.targetId).name }} <text v-if="item.conversationType === 3" <view class="name">
class='qun'>[]</text></view> {{ contact(item.targetId).name }}
<text v-if="item.conversationType === 3" class='group'>[]</text>
</view>
<view class="time">{{ item.sentTime|timeCustomCN }}</view> <view class="time">{{ item.sentTime|timeCustomCN }}</view>
</view> </view>
<message-preview class="preview" :msg="item.latestMessage" :draft="item.draft" <message-preview class="preview" :msg="item.latestMessage" :draft="item.draft"
@@ -80,10 +82,8 @@
.name { .name {
font-size: $title-size + 2; font-size: $title-size + 2;
color: #454545; color: #454545;
display: flex;
align-items: center;
.qun { .group {
color: $main-color; color: $main-color;
font-size: $title-size-m - 4; font-size: $title-size-m - 4;
margin-left: 4px; margin-left: 4px;

View File

@@ -1,12 +1,14 @@
<template> <template>
<view class="send--voice"> <view class="send--voice">
<view class="voice" hover-class="chat-hover" @touchstart="startRecord" @touchend="stopRecord"> <view class="voice" hover-class="chat-hover" @click="onShowLay">
<text class="button">按住说话</text> <text class="button">按住说话</text>
</view> </view>
<!-- 录音中提示 --> <!-- 录音中提示 -->
<view class="modal" v-if="showRecordTip"> <view class="voice--lay" v-if="showRecordTip" @touchstart="startRecord" @touchend="stopRecord">
<image class="icon" src="@/static/icon/record-icon.png" mode="widthFix"></image> <view class="modal">
<text class="text">录音中 {{recordTime}} s</text> <image class="icon" src="@/static/icon/record-icon.png" mode="widthFix"></image>
<text class="text">录音中 {{recordTime}} s</text>
</view>
</view> </view>
</view> </view>
</template> </template>
@@ -44,6 +46,14 @@
this.recorderManager = uni.getRecorderManager() this.recorderManager = uni.getRecorderManager()
}, },
methods: { methods: {
onShowLay(){
// this.showRecordTip = true
uni.vibrateShort({
complete: com => {
console.log(com)
}
})
},
// 检查安卓录制权限 // 检查安卓录制权限
async getAndroidPermission() { async getAndroidPermission() {
return await permision.requestAndroidPermission('android.permission.RECORD_AUDIO') return await permision.requestAndroidPermission('android.permission.RECORD_AUDIO')
@@ -116,6 +126,15 @@
} }
} }
.voice--lay{
position: absolute;
left: 0;
bottom: 0;
background: rgba($color: #000000, $alpha: .2);
height: 100vh;
width: 100vw;
}
.modal { .modal {
display: flex; display: flex;
background: rgba(0, 0, 0, .6); background: rgba(0, 0, 0, .6);

View File

@@ -0,0 +1,81 @@
<template>
<view v-if="!isRemote">
<view class="state" v-if="isGroup">
<!-- 已发送 -->
<u-icon name="checkbox-mark" :size="iconSize" class="sent"
:color="message.sentStatus >= 30 ? '#34CE98' : '#999999' " />
<!-- 已阅读 -->
<text class="readers">{{ readers }}</text>
</view>
<view class="state" v-else>
<!-- 已发送 -->
<u-icon name="checkbox-mark" :size="iconSize" class="sent"
:color="message.sentStatus >= 30 ? '#34CE98' : '#999999' " />
<!-- 已阅读 -->
<u-icon name="checkbox-mark" :size="iconSize" class="receive"
:color="message.sentStatus >= 50 ? '#34CE98' : '#999999' " />
</view>
</view>
</template>
<script>
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
import utils from '@/utils/index.js'
export default {
name: 'showText',
props: {
message: {
type: Object,
default: () => {
return {}
}
},
isGroup: {
type: Boolean,
default: false
},
isRemote: {
type: Boolean,
default: false
}
},
computed: {
iconSize() {
return utils.rpx2px(28)
},
readers() {
if (this.message.extra) {
return JSON.parse(this.message.extra).readers || 0
}
return 0
}
}
}
</script>
<style scoped lang="scss">
.state {
padding: 10rpx;
border-radius: 30rpx;
background-color: #ddd;
display: flex;
margin-right: 10rpx;
.sent {
z-index: 2;
}
.receive {
z-index: 1;
margin-left: -20rpx;
}
.readers {
font-size: 20rpx;
margin-left: -6rpx;
color: $text-gray-m;
}
}
</style>

View File

@@ -1,10 +1,9 @@
<template> <template>
<view class="msg--call"> <view class="msg--call">
<view class="name" v-if="!guest && name">{{ name }}</view> <view class="name" v-if="isGroup && isRemote">{{ contact(message.senderUserId).name }}</view>
<view class="im--text" :class="guest ? 'right': 'left'"> <view class="im--text" :class="isRemote ? 'left': 'right'">
<u-icon name="camera" size="22" v-if="message.mediaType == 1" <u-icon name="camera" size="22" v-if="msg.mediaType == 1" :label="label" />
:label="message.connected ? '通话时长:' + duration : '未接通'" /> <u-icon name="phone" size="22" v-else :label="label" />
<u-icon name="phone" size="22" v-else :label="message.connected ? '通话时长:' + duration : '未接通'" />
</view> </view>
</view> </view>
</template> </template>
@@ -16,24 +15,33 @@
export default { export default {
name: 'showText', name: 'showText',
props: { props: {
msg: { message: {
type: Object, type: Object,
default: () => { default: () => {
return {} return {}
} }
}, },
name: { isGroup: {
type: String,
default: ''
},
guest: {
type: Boolean, type: Boolean,
default: true default: false
} }
}, },
mounted() {
},
computed: { computed: {
message() { msg() {
return JSON.parse(this.msg.message) return JSON.parse(this.message.content.message)
},
label() {
return this.msg.connected ? '通话时长:' + duration : '未接通'
},
isRemote() {
return this.message.messageDirection == 2
},
contact() {
return function(targetId) {
return this.$store.getters.contactInfo(targetId)
}
}, },
duration() { duration() {
if (this.message.duration > 3600) { if (this.message.duration > 3600) {

View File

@@ -1,14 +1,19 @@
<template> <template>
<view class=""> <view class="msg--image">
<view class="name" v-if="isGroup && isRemote">{{ contact(message.senderUserId).name }}</view> <message-state :message="message" :isGroup="isGroup" :isRemote="isRemote" />
<view class="msg--image" :class="isRemote ? 'left': 'right'">
<image class="img" :src="content.thumbnail" @click="previewImage" mode="widthFix"></image> <view class="">
<view class="name" v-if="isGroup && isRemote">{{ contact(message.senderUserId).name }}</view>
<view class="image" :class="isRemote ? 'left': 'right'">
<image class="img" :src="content.thumbnail" @click="previewImage" mode="widthFix"></image>
</view>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index' import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
import messageState from './messageState'
export default { export default {
name: 'showImage', name: 'showImage',
@@ -24,6 +29,9 @@
default: false default: false
} }
}, },
components: {
messageState
},
computed: { computed: {
isRemote() { isRemote() {
return this.message.messageDirection == 2 return this.message.messageDirection == 2
@@ -38,43 +46,27 @@
} }
}, },
methods: { methods: {
showImage(path) {
uni.previewImage({
urls: [
path
]
})
},
previewImage() { previewImage() {
if (this.content.local) { if (this.content.local && this.content.local.indexOf('///data/user/') < 0) {
uni.previewImage({ this.showImage(this.content.local)
urls: [
this.content.local
],
success: (e) => {
console.log(e);
},
fail: (er) => {
console.log(er);
}
})
} else { } else {
RongIMLib.downloadMediaMessage(this.messageId, { RongIMLib.downloadMediaMessage(this.message.messageId, {
success: (path) => { success: (path) => {
this.content.local = path this.content.local = path
uni.previewImage({ this.showImage(path)
urls: [
path
],
success: (e) => {
console.log(e);
},
fail: (er) => {
console.log(er);
}
})
},
progress: (progress, messageId) => {
console.log('progress', progress);
},
cancel: (messageId) => {
console.log('cancel', messageId);
}, },
error: (errorCode, messageId) => { error: (errorCode, messageId) => {
console.log('errorCode', errorCode); uni.showToast({
icon: 'none',
title: errorCode
})
} }
}) })
} }
@@ -84,27 +76,31 @@
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.name {
font-size: 24rpx;
color: $text-gray-m;
}
.msg--image { .msg--image {
.img { display: flex;
width: 180rpx; align-items: flex-end;
.name {
font-size: 24rpx;
color: $text-gray-m;
} }
&.left { .image {
.img { .img {
border-radius: 0 10rpx 10rpx 10rpx; width: 180rpx;
}
&.left {
.img {
border-radius: 0 10rpx 10rpx 10rpx;
}
}
&.right {
.img {
border-radius: 10rpx 0 10rpx 10rpx;
}
} }
} }
&.right {
.img {
border-radius: 10rpx 0 10rpx 10rpx;
}
}
} }
</style> </style>

View File

@@ -1,20 +1,16 @@
<template> <template>
<view class="msg--text"> <view class="msg--text">
<view class="state" v-if="!isGroup && !isRemote"> <message-state :message="message" :isGroup="isGroup" :isRemote="isRemote" />
<!-- 已发送 -->
<u-icon name="checkbox-mark" class="sent" :color="message.sentStatus >= 30 ? '#34CE98' : '#999999' " />
<!-- 已阅读 -->
<u-icon name="checkbox-mark" class="receive" :color="message.sentStatus >= 50 ? '#34CE98' : '#999999' " />
</view>
<view class=""> <view class="">
<view class="name" v-if="isGroup && isRemote">{{ contact(message.senderUserId).name }}</view> <view class="name" v-if="isGroup && isRemote">{{ contact(message.senderUserId).name }}</view>
<view @longpress="backMessage" :class="['text', isRemote ? 'left': 'right']">{{ content }}</view> <view :class="['text', isRemote ? 'left': 'right']">{{ content }}</view>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index' import messageState from './messageState'
export default { export default {
name: 'showText', name: 'showText',
@@ -30,6 +26,9 @@
default: false default: false
} }
}, },
components: {
messageState
},
computed: { computed: {
isRemote() { isRemote() {
return this.message.messageDirection == 2 return this.message.messageDirection == 2
@@ -42,42 +41,6 @@
return this.$store.getters.contactInfo(targetId) return this.$store.getters.contactInfo(targetId)
} }
} }
},
methods: {
// 撤回消息测试
backMessage() {
if (this.$store.getters.sender.userId != this.message.senderUserId) {
uni.showToast({
icon: 'none',
title: '不能撤回别人的消息'
})
return
}
// 判断时间超过了多久 就不能撤回 TODO
// this.message.sentTime
const pushContent = this.$store.getters.sender.name + '撤回了一条消息'
RongIMLib.recallMessage(this.message.messageId, pushContent,
({
code,
message
}) => {
if (code === 0) {
uni.showToast({
icon: 'none',
title: '消息撤回成功'
})
RongIMLib.getMessage(this.message.messageId, res => {
uni.$emit('onRecallMessage', res.message)
})
} else {
uni.showToast({
icon: 'none',
title: '撤回失败' + code
})
}
}
)
}
} }
} }
</script> </script>
@@ -87,24 +50,6 @@
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;
.state {
padding: 10rpx;
border-radius: 30rpx;
width: 40rpx;
background-color: #ddd;
display: flex;
margin-right: 10rpx;
.sent {
z-index: 2;
}
.receive {
z-index: 1;
margin-left: -20rpx;
}
}
.name { .name {
font-size: 24rpx; font-size: 24rpx;
color: $text-gray-m; color: $text-gray-m;

View File

@@ -1,22 +1,30 @@
<template> <template>
<view class=""> <view class="msg--voice">
<view class="name" v-if="isGroup && isRemote">{{ contact(message.senderUserId).name }}</view> <message-state :message="message" :isGroup="isGroup" :isRemote="isRemote" />
<view class="msg--voice">
<view :class="['voice', isRemote ? 'left': 'right', {'onPlay': onPlay}]" :style="{width: width + 'rpx'}" @click="startPlay"> <view class="">
<image v-if="isRemote" class="icon" :class="{ 'videoFlicker' : onPlay && msgId == message.messageId }" src="@/static/icon/audio_green.png" mode="widthFix"></image> <view class="name" v-if="isGroup && isRemote">{{ contact(message.senderUserId).name }}</view>
<image v-else class="icon" :class="{ 'videoFlicker' : onPlay && msgId == message.messageId }" src="@/static/icon/audio_white.png" mode="widthFix"></image> <view class="msg-voice">
<text class="duration">{{ duration }}"</text> <view :class="['voice', isRemote ? 'left': 'right', {'onPlay': onPlay}]" :style="{width: width + 'rpx'}"
@click="startPlay">
<image v-if="isRemote" class="icon"
:class="{ 'videoFlicker' : onPlay && msgId == message.messageId }"
src="@/static/icon/audio_green.png" mode="widthFix"></image>
<image v-else class="icon" :class="{ 'videoFlicker' : onPlay && msgId == message.messageId }"
src="@/static/icon/audio_white.png" mode="widthFix"></image>
<text class="duration">{{ duration }}"</text>
</view>
<u-badge isDot :show="message.content.local =='' && isRemote" />
</view> </view>
<u-badge isDot :show="message.content.local =='' && isRemote" />
</view> </view>
</view> </view>
</template> </template>
<script> <script>
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index' import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
import messageState from './messageState'
export default { export default {
name: 'showVoice',
props: { props: {
message: { message: {
type: Object, type: Object,
@@ -29,11 +37,14 @@
default: false default: false
} }
}, },
components: {
messageState
},
data() { data() {
return { return {
onPlay: false, onPlay: false,
innerAC: null, innerAC: null,
msgId : null msgId: null
} }
}, },
computed: { computed: {
@@ -64,11 +75,6 @@
} }
}) })
}, },
created() {
console.log(this.message.messageId)
},
methods: { methods: {
// 播放语音消息 // 播放语音消息
startPlay() { startPlay() {
@@ -77,8 +83,9 @@
this.stopPlay() this.stopPlay()
return return
} }
this.onPlay = true
// 如果下载到了本地,那么直接播放,否则调用下载语音消息接口,下载后再播放 // 如果下载到了本地,那么直接播放,否则调用下载语音消息接口,下载后再播放
if (this.message.content.local) { if (this.message.content.local && this.message.content.local.indexOf('///data/user/') < 0) {
this.playVoice(this.message.content.local) this.playVoice(this.message.content.local)
} else { } else {
RongIMLib.downloadMediaMessage(this.message.messageId, { RongIMLib.downloadMediaMessage(this.message.messageId, {
@@ -104,11 +111,11 @@
this.innerAC.autoplay = false this.innerAC.autoplay = false
this.msgId = this.message.messageId this.msgId = this.message.messageId
this.innerAC.onCanplay(res => { this.innerAC.onCanplay(res => {
console.log('onCanplay')
this.innerAC.play() this.innerAC.play()
}) })
this.innerAC.onPlay(res => { this.innerAC.onPlay(res => {
this.onPlay = true console.log('onPlay')
uni.$emit('onVoiceMessagePlay', this.message.messageId) uni.$emit('onVoiceMessagePlay', this.message.messageId)
}) })
this.innerAC.onEnded(res => { this.innerAC.onEnded(res => {
@@ -118,7 +125,7 @@
this.onPlay = false this.onPlay = false
this.innerAC.destroy() this.innerAC.destroy()
this.innerAC = null this.innerAC = null
this.msgId = null this.msgId = null
uni.$emit('onVoiceMessageStop', this.message.messageId) uni.$emit('onVoiceMessageStop', this.message.messageId)
}) })
this.innerAC.onError(err => { this.innerAC.onError(err => {
@@ -129,7 +136,6 @@
}) })
}, },
stopPlay() { stopPlay() {
// 停止播放语音消息
if (this.innerAC) { if (this.innerAC) {
this.innerAC.stop() this.innerAC.stop()
} }
@@ -139,77 +145,102 @@
</script> </script>
<style> <style>
@keyframes playFlicker{ @keyframes playFlicker {
0%{ 0% {
opacity: 1; opacity: 1;
} }
50%{
50% {
opacity: .5; opacity: .5;
} }
100%{
100% {
opacity: 1; opacity: 1;
} }
} }
.videoFlicker{ .videoFlicker {
animation: playFlicker 1s infinite; animation: playFlicker 1s infinite;
} }
</style> </style>
<style scoped lang="scss"> <style scoped lang="scss">
.name {
font-size: 24rpx;
color: $text-gray-m;
}
.msg--voice { .msg--voice {
display: flex; display: flex;
align-items: center; align-items: flex-end;
.u-badge { .state {
margin-left: 20rpx; padding: 10rpx;
border-radius: 30rpx;
width: 40rpx;
background-color: #ddd;
display: flex;
margin-right: 10rpx;
.sent {
z-index: 2;
}
.receive {
z-index: 1;
margin-left: -20rpx;
}
} }
.voice { .name {
font-size: 24rpx;
color: $text-gray-m;
}
.msg-voice {
display: flex; display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center; align-items: center;
height: 84rpx;
padding: 0 30rpx;
box-sizing: border-box;
.icon { .u-badge {
width: 38rpx; margin-left: 20rpx;
height: 38rpx;
} }
&.left { .voice {
border-radius: 0 20rpx 20rpx 20rpx; display: flex;
background: white; flex-direction: row;
justify-content: space-between;
align-items: center;
height: 84rpx;
padding: 0 30rpx;
box-sizing: border-box;
&.onPlay { .icon {
background-color: #EEEEEE; width: 38rpx;
height: 38rpx;
} }
.duration { &.left {
color: #333; border-radius: 0 20rpx 20rpx 20rpx;
font-size: 30rpx; background: white;
}
}
&.right { &.onPlay {
border-radius: 20rpx 0 20rpx 20rpx; background-color: #EEEEEE;
background: $main-color; }
flex-direction: row-reverse;
&.onPlay { .duration {
background-color: darken($main-color, 10); color: #333;
font-size: 30rpx;
}
} }
.duration { &.right {
color: white; border-radius: 20rpx 0 20rpx 20rpx;
font-size: 30rpx; background: $main-color;
flex-direction: row-reverse;
&.onPlay {
background-color: darken($main-color, 10);
}
.duration {
color: white;
font-size: 30rpx;
}
} }
} }
} }

View File

@@ -7,7 +7,7 @@
<view v-else :class="['cell-item', message.messageDirection == 1 ? 'right' : 'left']"> <view v-else :class="['cell-item', message.messageDirection == 1 ? 'right' : 'left']">
<u-avatar class="avatar" @click="toUser(message)" :size="avatarSize" shape="square" <u-avatar class="avatar" @click="toUser(message)" :size="avatarSize" shape="square"
:src="contact(message.senderUserId).portraitUrl" /> :src="contact(message.senderUserId).portraitUrl" />
<view class="msg"> <view class="msg" @longpress="backMessage">
<show-text v-if="message.objectName === 'RC:TxtMsg'" :message="message" :isGroup="isGroup" /> <show-text v-if="message.objectName === 'RC:TxtMsg'" :message="message" :isGroup="isGroup" />
<show-voice v-else-if="message.objectName === 'RC:HQVCMsg'" :message="message" :isGroup="isGroup" /> <show-voice v-else-if="message.objectName === 'RC:HQVCMsg'" :message="message" :isGroup="isGroup" />
<show-image v-else-if="message.objectName === 'RC:ImgMsg'" :message="message" :isGroup="isGroup" /> <show-image v-else-if="message.objectName === 'RC:ImgMsg'" :message="message" :isGroup="isGroup" />
@@ -22,6 +22,7 @@
</template> </template>
<script> <script>
import * as IMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
import showVoice from './show/showVoice' import showVoice from './show/showVoice'
import showImage from './show/showImage' import showImage from './show/showImage'
import showText from './show/showText' import showText from './show/showText'
@@ -73,6 +74,40 @@
url: '/pages/im/friends/info?targetId=' + item.senderUserId url: '/pages/im/friends/info?targetId=' + item.senderUserId
}) })
} }
},
// 撤回消息测试
backMessage() {
if (this.$store.getters.sender.userId != this.message.senderUserId) {
uni.showToast({
icon: 'none',
title: '不能撤回别人的消息'
})
return
}
// 判断时间超过了多久 就不能撤回 TODO
// this.message.sentTime
const pushContent = this.$store.getters.sender.name + '撤回了一条消息'
IMLib.recallMessage(this.message.messageId, pushContent,
({
code,
message
}) => {
if (code === 0) {
uni.showToast({
icon: 'none',
title: '消息撤回成功'
})
IMLib.getMessage(this.message.messageId, res => {
uni.$emit('onRecallMessage', res.message)
})
} else {
uni.showToast({
icon: 'none',
title: '撤回失败' + code
})
}
}
)
} }
} }
} }

View File

@@ -2,40 +2,33 @@
<view> <view>
<u-index-list :index-list="indexs" inactiveColor="#666" activeColor="#34CE98"> <u-index-list :index-list="indexs" inactiveColor="#666" activeColor="#34CE98">
<view class="friend-flex" @click="toPending"> <view class="friend-flex" @click="toPending">
<u-avatar class="cover" size="40" shape="square" :src="require('@/static/im/im_01.png')"></u-avatar> <u-avatar class="cover" size="40" shape="square" :src="require('@/static/im/im_01.png')" />
<u-badge max="99" absolute :offset="[23, 20]" :value="pendingCount" /> <u-badge max="99" absolute :offset="[23, 20]" :value="pendingCount" />
<view class="info">新的朋友</view> <view class="info">新的朋友</view>
</view> </view>
<view class="friend-flex" @click="toGroup"> <view class="friend-flex" @click="toGroup">
<u-avatar class="cover" size="40" shape="square" :src="require('@/static/im/im_00.png')"></u-avatar> <u-avatar class="cover" size="40" shape="square" :src="require('@/static/im/im_00.png')" />
<view class="info">我的群聊</view> <view class="info">我的群聊</view>
</view> </view>
<block v-if="friends.length > 0"> <block v-if="friends.length > 0">
<u-index-item v-for="(item, fkey) in friends" :key="fkey"> <u-index-item v-for="(item, fkey) in friends" :key="fkey">
<u-index-anchor :text="indexs[fkey]" bgColor="#f9f9f9" height="20" size="12" color="#666" <u-index-anchor :text="indexs[fkey]" bgColor="#f9f9f9" height="20" size="12" color="#666" class="anchor" />
class="anchor" /> <view v-for="(friendItem, index) in item" :key="index" class="friend-flex" @click="toFriend(friendItem.targetId)">
<view v-for="(friendItem, index) in item" :key="index" class="friend-flex" <u-avatar class="avatar-img" size="40" shape="square" :src="contact(friendItem.targetId).portraitUrl" />
@click="toFriend(friendItem.targetId)"> <view class="info"> <view class="name">{{ contact(friendItem.targetId).name }}</view> </view>
<u-avatar class="avatar-img" size="40" shape="square"
:src="contact(friendItem.targetId).portraitUrl" />
<view class="info">
<view class="name">{{ contact(friendItem.targetId).name }}</view>
<!-- <view class="address">地址:{{ friendItem.address }}</view> -->
</view>
</view> </view>
</u-index-item> </u-index-item>
</block> </block>
<block v-else> <view class="no-lists" v-else>
<u-empty class="pages-null" mode="data" text="暂无好友" /> <u-image class="cover" radius="4" width="400rpx" height="400rpx" :src=" require('@/static/imgs/no-friend.png')" :lazy-load="true" />
</block> <span>暂无好友列表~</span>
</view>
</u-index-list> </u-index-list>
</view> </view>
</template> </template>
<script> <script>
import { import {getFriendsLetter} from '@/apis/interfaces/im';
getFriendsLetter
} from '@/apis/interfaces/im';
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index' import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
import im from '@/utils/im/index.js' import im from '@/utils/im/index.js'
@@ -54,14 +47,18 @@
} }
} }
}, },
onLoad() { onShow() {
this.getFriendList() this.getFriendList()
this.checkNewFriendPending() this.checkNewFriendPending()
uni.$on('onContactNotification', this.checkNewFriendPending) uni.$on('onContactNotification', this.checkNewFriendPending)
}, },
onUnload() {
uni.$off("onContactNotification")
},
methods: { methods: {
getFriendList() { getFriendList() {
getFriendsLetter().then(res => { getFriendsLetter().then(res => {
console.log(res)
this.indexs = res.indexList this.indexs = res.indexList
this.friends = res.itemArr this.friends = res.itemArr
}) })
@@ -86,18 +83,9 @@
}, },
// 新朋友 // 新朋友
toPending() { toPending() {
// if (this.pendingCount > 0) {
uni.navigateTo({ uni.navigateTo({
url: '/pages/im/friends/pending' url: '/pages/im/friends/pending'
}); });
// } else {
// uni.showToast({
// title: ` 暂无好友申请 ~ `,
// icon: "none",
// mask: true,
// duration: 3000
// })
// }
} }
}, },
onNavigationBarButtonTap(e) { onNavigationBarButtonTap(e) {
@@ -172,4 +160,18 @@
line-height: 24px; line-height: 24px;
background-color: #fff; background-color: #fff;
} }
.no-lists {
padding-top: $padding * 3;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-sizing: border-box;
font-size: $title-size-m;
color: $text-gray-m;
span {
padding-top: $padding;
}
}
</style> </style>

View File

@@ -113,7 +113,6 @@
onLoad(e) { onLoad(e) {
this.targetId = e.targetId this.targetId = e.targetId
getFriendInfo(e.targetId).then(res => { getFriendInfo(e.targetId).then(res => {
console.log(res, "获取朋友的信息")
this.userInfo = res this.userInfo = res
// 获取到用户信息之后,去检查一下要不要更新 // 获取到用户信息之后,去检查一下要不要更新
this.$store.dispatch('updateContact', res) this.$store.dispatch('updateContact', res)
@@ -148,7 +147,7 @@
}) })
}, },
toPrivate() { toPrivate() {
uni.redirectTo({ uni.navigateTo({
url: '/pages/im/private/chat?targetId=' + this.targetId url: '/pages/im/private/chat?targetId=' + this.targetId
}); });
}, },
@@ -209,7 +208,7 @@
}) })
return return
} }
pedingFriend(this.targetId, 'message').then(res => { pedingFriend(this.targetId, '').then(res => {
uni.showToast({ uni.showToast({
title: ` 申请成功,等待审核 `, title: ` 申请成功,等待审核 `,
icon: 'none', icon: 'none',
@@ -228,8 +227,9 @@
}) })
}, },
singleCall(e) { singleCall(e) {
uni.redirectTo({ uni.navigateTo({
url: '/pages/im/private/call?targetId=' + this.targetId + '&mediaType=' + e.type + '&isCall=true' url: '/pages/im/private/call?targetId=' + this.targetId + '&mediaType=' + e.type +
'&isCall=true'
}) })
} }
} }

View File

@@ -6,8 +6,15 @@
:disabled="true" :show-action="false" /> :disabled="true" :show-action="false" />
</view> </view>
</u-sticky> </u-sticky>
<view v-for="(item, index) in pendings" :key="index"> <block v-if="pendings.length > 0">
<apply-cell :message="item.latestMessage" @success="getPendingList" /> <view v-for="(item, index) in pendings" :key="index">
<apply-cell :message="item.latestMessage" @success="getPendingList" />
</view>
</block>
<view class="no-lists" v-else>
<u-image class="cover" radius="4" width="400rpx" height="400rpx"
:src="require('@/static/imgs/no-friend.png')" :lazy-load="true" />
<span> 暂无好友申请 ~ </span>
</view> </view>
</view> </view>
</template> </template>
@@ -22,16 +29,26 @@
}, },
data() { data() {
return { return {
pendings: [] pendings: [],
bg: '#fff'
} }
}, },
onLoad() { onShow() {
this.getPendingList() this.getPendingList()
uni.$on('onContactNotification', this.getPendingList) uni.$on('onNewContactPendings', this.getPendingList)
},
onUnload() {
uni.$off('onNewContactPendings')
}, },
methods: { methods: {
getPendingList() { getPendingList() {
im.getPendingList((pendings) => { im.getPendingList((pendings) => {
console.log(pendings,'res......')
if (pendings.length > 0) {
this.bg = '#f9f9f9'
} else {
this.bg = '#fff'
}
this.pendings = pendings this.pendings = pendings
}) })
} }
@@ -46,7 +63,7 @@
} }
.no-lists { .no-lists {
padding-top: $padding * 3; padding-top: $padding * 5;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;

View File

@@ -16,8 +16,12 @@
createGroupAnnouncement, createGroupAnnouncement,
getGroupAnnouncement getGroupAnnouncement
} from '@/apis/interfaces/im.js' } from '@/apis/interfaces/im.js'
import onGroupDismiss from '@/utils/im/onGroupDismiss.js'
export default { export default {
mixins: [
onGroupDismiss
],
data() { data() {
return { return {
targetId: '', targetId: '',

View File

@@ -35,8 +35,12 @@
deleteGroupAnnouncement, deleteGroupAnnouncement,
topGroupAnnouncement topGroupAnnouncement
} from '@/apis/interfaces/im.js' } from '@/apis/interfaces/im.js'
import onGroupDismiss from '@/utils/im/onGroupDismiss.js'
export default { export default {
mixins: [
onGroupDismiss
],
data() { data() {
return { return {
targetId: '', targetId: '',
@@ -55,7 +59,7 @@
disabled: false disabled: false
}], }],
actionTitle: '请选择操作', actionTitle: '请选择操作',
bg:'#fff' bg: '#fff'
} }
}, },
onLoad(e) { onLoad(e) {
@@ -85,9 +89,9 @@
// 获取公告信息 // 获取公告信息
initData() { initData() {
getGroupAnnouncements(this.targetId).then(res => { getGroupAnnouncements(this.targetId).then(res => {
if(res.length>0){ if (res.length > 0) {
this.bg = '#f9f9f9' this.bg = '#f9f9f9'
}else{ } else {
this.bg = '#fff' this.bg = '#fff'
} }
this.announcements = res this.announcements = res
@@ -215,7 +219,7 @@
-webkit-line-clamp: 3; -webkit-line-clamp: 3;
overflow: hidden; overflow: hidden;
line-height: 1.5; line-height: 1.5;
border-bottom: solid 1rpx #F9F9F9; border-bottom: solid 1rpx #F9F9F9;
padding-bottom: 20rpx; padding-bottom: 20rpx;
span { span {

View File

@@ -20,8 +20,12 @@
joinGroupPre, joinGroupPre,
joinGroup joinGroup
} from '@/apis/interfaces/im.js' } from '@/apis/interfaces/im.js'
import onGroupDismiss from '@/utils/im/onGroupDismiss.js'
export default { export default {
mixins: [
onGroupDismiss
],
data() { data() {
return { return {
targetId: '', targetId: '',

View File

@@ -21,8 +21,12 @@
import sentMessageBar from '../components/sentMessageBar' import sentMessageBar from '../components/sentMessageBar'
import showMessageCell from '../components/showMessageCell' import showMessageCell from '../components/showMessageCell'
import utils from '@/utils/index.js' import utils from '@/utils/index.js'
import onGroupDismiss from '@/utils/im/onGroupDismiss.js'
export default { export default {
mixins: [
onGroupDismiss
],
components: { components: {
sentMessageBar, sentMessageBar,
showMessageCell showMessageCell
@@ -59,11 +63,9 @@
}) })
// 获取历史消息列表 // 获取历史消息列表
this.getMessageList() this.getMessageList()
// 监听收到本群的消息,追加消息 // 监听消息
uni.$on('onReceiveMessage', (msg) => { uni.$on('onReceiveMessage_' + this.targetId, (message) => {
if (msg.targetId == this.targetId) { this.getNewMessage()
this.getNewMessage()
}
}) })
uni.$on('onReceiptRequest', (msg) => { uni.$on('onReceiptRequest', (msg) => {
if (msg.targetId == this.targetId) { if (msg.targetId == this.targetId) {
@@ -74,8 +76,17 @@
}) })
} }
}) })
// 群已读回执
uni.$on('onReceiptResponse', (msg) => { uni.$on('onReceiptResponse', (msg) => {
console.log('远端消息已读,本地获取有几个人读了', msg); if (msg.targetId == this.targetId) {
this.messages = this.messages.map(item => {
if (msg.messageId == item.messageId) {
return msg
} else {
return item
}
})
}
}) })
// 清理聊天记录 // 清理聊天记录
uni.$once('cleanGroupMessage', this.getMessageList) uni.$once('cleanGroupMessage', this.getMessageList)
@@ -92,6 +103,7 @@
}) })
}, },
onUnload() { onUnload() {
uni.$off('onReceiveMessage_' + this.targetId)
uni.$off('onRecallMessage') uni.$off('onRecallMessage')
uni.$off('onReceiptRequest') uni.$off('onReceiptRequest')
uni.$off('onReceiptResponse') uni.$off('onReceiptResponse')
@@ -127,9 +139,17 @@
true, true,
(messages) => { (messages) => {
console.log('获取消息列表', messages); console.log('获取消息列表', messages);
RongIMLib.sendReadReceiptResponse(3, this.targetId, messages, (res) => { const msgs = messages.filter(item => item.receivedStatus == 0)
console.error('发送群聊已读回执成功', res); console.log('未读消息', msgs);
}) if (msgs.length) {
RongIMLib.sendReadReceiptResponse(3, this.targetId, msgs, (res) => {
console.error('发送群聊已读回执成功', res);
msgs.map(item => {
RongIMLib.setMessageReceivedStatus(item.messageId, 1)
})
})
}
this.messages = messages this.messages = messages
this.scrollBottom() this.scrollBottom()
}) })
@@ -147,7 +167,7 @@
}, },
onHide() { onHide() {
// console.log(JSON.stringify(this.$refs)) // console.log(JSON.stringify(this.$refs))
this.$refs.voice.stopPlay() // this.$refs.voice.stopPlay()
} }
} }
</script> </script>

View File

@@ -1,13 +1,20 @@
<template> <template>
<view class="group"> <view class="group" :style="`background-color:${bg};`">
<view class="title"> 群聊 </view> <block v-if="groups.length > 0">
<view v-for="(item, index) in groups" :key="index" class="friend-flex" @click="toGroup(item.targetId)"> <view class="title"> 群聊 </view>
<u-avatar size="38" shape="square" :src="contact(item.targetId).portraitUrl" /> <view v-for="(item, index) in groups" :key="index" class="friend-flex" @click="toGroup(item.targetId)">
<view class="info"> <u-avatar size="38" shape="square" :src="contact(item.targetId).portraitUrl" />
<view class="name">{{ item.name }}</view> <view class="info">
<view class="name">{{item.name}} <span class="total">共10人</span></view>
</view>
</view> </view>
<view class="group-count"> {{groups.length}}个群聊 </view>
</block>
<view class="no-lists" v-else>
<u-image class="cover" radius="4" width="400rpx" height="400rpx"
:src="require('@/static/imgs/no-friend.png')" :lazy-load="true" />
<span>空空如也~</span>
</view> </view>
<view class="group-count"> {{groups.length}}个群聊 </view>
<u-modal negativeTop="300" :show="createModal" title="创建群聊" showCancelButton @cancel="onHideModal" <u-modal negativeTop="300" :show="createModal" title="创建群聊" showCancelButton @cancel="onHideModal"
@confirm="onCreateGroup"> @confirm="onCreateGroup">
<view class="slot-content"> <view class="slot-content">
@@ -28,7 +35,8 @@
return { return {
groups: [], groups: [],
createModal: false, createModal: false,
groupName: '' groupName: '',
bg: '#fff'
} }
}, },
computed: { computed: {
@@ -41,13 +49,18 @@
onNavigationBarButtonTap() { onNavigationBarButtonTap() {
this.createModal = true this.createModal = true
}, },
onLoad() { onShow() {
this.initData() this.initData()
uni.$on('onGroupDismiss', this.initData) uni.$on('onGroupDismiss', this.initData)
}, },
methods: { methods: {
initData() { initData() {
getMyGroups().then((res) => { getMyGroups().then((res) => {
if (res.length > 0) {
this.bg = '#f9f9f9'
} else {
this.bg = '#fff'
}
this.groups = res this.groups = res
res.map(item => { res.map(item => {
this.$store.dispatch('updateContact', item) this.$store.dispatch('updateContact', item)
@@ -88,12 +101,14 @@
.group { .group {
min-height: 100vh; min-height: 100vh;
background-color: $window-color; background-color: $window-color;
.title{
.title {
font-size: $title-size-m; font-size: $title-size-m;
color: $text-gray-m; color: $text-gray-m;
padding: 10rpx $padding; padding: 10rpx $padding;
} }
.group-count{
.group-count {
text-align: center; text-align: center;
font-size: $title-size; font-size: $title-size;
color: $text-gray; color: $text-gray;
@@ -123,6 +138,11 @@
font-size: $title-size + 1; font-size: $title-size + 1;
color: #454545 !important; color: #454545 !important;
} }
.total{
color: $text-gray-m;
font-size: $title-size-m - 5;
padding-left: 10rpx;
}
.address { .address {
color: $text-gray-m; color: $text-gray-m;
@@ -130,4 +150,19 @@
} }
} }
} }
.no-lists {
padding-top: $padding * 5;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-sizing: border-box;
font-size: $title-size-m;
color: $text-gray-m;
span {
padding-top: $padding;
}
}
</style> </style>

View File

@@ -9,8 +9,7 @@
<view slot="label" class="announcement-label "> {{announcement}} </view> <view slot="label" class="announcement-label "> {{announcement}} </view>
</u-cell> </u-cell>
<u-cell :border="false" class="u-border-bottom" isLink title="二维码" @click="showGroupQrCode" /> <u-cell :border="false" class="u-border-bottom" isLink title="二维码" @click="showGroupQrCode" />
<u-cell :border="false" class="u-border-bottom" v-if="group.can_makesure" isLink title="群聊邀请确认" <u-cell :border="false" class="u-border-bottom" v-if="group.can_makesure" isLink title="群聊邀请确认" @click="showGroupsSure" />
@click="showGroupsSure" />
<u-cell :border="false" class="u-border-bottom" title="聊天置顶"> <u-cell :border="false" class="u-border-bottom" title="聊天置顶">
<u-switch slot="value" size="20" v-model="isTop" activeColor="#34CE98" @change="setTop" /> <u-switch slot="value" size="20" v-model="isTop" activeColor="#34CE98" @change="setTop" />
</u-cell> </u-cell>
@@ -25,8 +24,7 @@
<u-cell :border="false" class="u-border-bottom" isLink title="修改群头像" @click="onGroupAvatar"> <u-cell :border="false" class="u-border-bottom" isLink title="修改群头像" @click="onGroupAvatar">
<u-avatar slot="value" size="25" shape="square" :src="group.cover" /> <u-avatar slot="value" size="25" shape="square" :src="group.cover" />
</u-cell> </u-cell>
<u-cell :border="false" class="u-border-bottom" isLink v-if="group.is_owner" title="准入方式" :value="joinType" <u-cell :border="false" class="u-border-bottom" isLink v-if="group.is_owner" title="准入方式" :value="joinType" @click="onChangeJoinType" />
@click="onChangeJoinType" />
</u-cell-group> </u-cell-group>
<view class="cells actions" v-if="loaded"> <view class="cells actions" v-if="loaded">
@@ -35,21 +33,15 @@
<view class="action u-border-bottom" v-else @click="onQuite">删除并退出</view> <view class="action u-border-bottom" v-else @click="onQuite">删除并退出</view>
</view> </view>
<u-modal negativeTop="300" :show="modalShow" title="修改群名称" showCancelButton @cancel="onHideModal" <u-modal negativeTop="300" :show="modalShow" title="修改群名称" showCancelButton @cancel="onHideModal" @confirm="onChangeGroupName">
@confirm="onChangeGroupName"> <view class="slot-content"> <u--input placeholder="群名称" border="surround" focus v-model="groupName" maxlength="14" /> </view>
<view class="slot-content">
<u--input placeholder="群名称" border="surround" focus v-model="groupName" />
</view>
</u-modal> </u-modal>
<u-modal :show="qrCodeShow" :title="group.name" @confirm="qrCodeShow = false"> <u-modal :show="qrCodeShow" :title="group.name" @confirm="qrCodeShow = false">
<view class="slot-content"> <view class="slot-content"> <uqrcode class="info-code-src" :size="198" :text="qrContent" /> </view>
<uqrcode class="info-code-src" :size="198" :text="qrContent" />
</view>
</u-modal> </u-modal>
<u-action-sheet @select="doAction" :actions="joinTypeMap" cancelText="取消" :show="showActions" <u-action-sheet @select="doAction" :actions="joinTypeMap" cancelText="取消" :show="showActions" @close="showActions=false" />
@close="showActions=false" />
</view> </view>
</template> </template>
@@ -65,11 +57,15 @@
} from '@/apis/interfaces/uploading' } from '@/apis/interfaces/uploading'
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index' import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
import groupUserList from '../components/groupUserList' import groupUserList from '../components/groupUserList'
import onGroupDismiss from '@/utils/im/onGroupDismiss.js'
export default { export default {
components: { components: {
groupUserList groupUserList
}, },
mixins: [
onGroupDismiss
],
data() { data() {
return { return {
targetId: '', targetId: '',
@@ -133,7 +129,6 @@
return item.key == res.join_type return item.key == res.join_type
})[0].name })[0].name
}).catch(err => { }).catch(err => {
console.log('getGroupInfo ERR', err);
uni.showToast({ uni.showToast({
icon: 'none', icon: 'none',
title: '群不存在' title: '群不存在'

View File

@@ -8,8 +8,9 @@
<u-index-list :index-list="indexs" inactiveColor="#666" activeColor="#34CE98"> <u-index-list :index-list="indexs" inactiveColor="#666" activeColor="#34CE98">
<u-checkbox-group v-if="friends.length > 0" v-model="checkboxValue" placement="column"> <u-checkbox-group v-if="friends.length > 0" v-model="checkboxValue" placement="column">
<u-index-item v-for="(item, fkey) in friends" :key="fkey"> <u-index-item v-for="(item, fkey) in friends" :key="fkey">
<u-index-anchor :text="indexs[fkey]" v-if="indexs[fkey]" bgColor="#f9f9f9f" height="20" size="12" <u-index-anchor :text="indexs[fkey]" v-if="indexs[fkey]" bgColor="#f9f9f9f" height="20"
color="#666" style="border:none !important;padding: 10rpx 30rpx;background-color: #f9f9f9 !important;" /> size="12" color="#666"
style="border:none !important;padding: 10rpx 30rpx;background-color: #f9f9f9 !important;" />
<view v-for="(friendItem, index) in item" :key="index" class="friend-flex" <view v-for="(friendItem, index) in item" :key="index" class="friend-flex"
@click="addContact(friendItem.targetId)"> @click="addContact(friendItem.targetId)">
<u-checkbox :name="friendItem.targetId" shape="circle" activeColor="#34ce98" <u-checkbox :name="friendItem.targetId" shape="circle" activeColor="#34ce98"
@@ -44,10 +45,13 @@
getGroupUsers getGroupUsers
} from '@/apis/interfaces/im'; } from '@/apis/interfaces/im';
import utils from '@/utils/index.js' import utils from '@/utils/index.js'
import onGroupDismiss from '@/utils/im/onGroupDismiss.js'
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index' import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
export default { export default {
mixins: [
onGroupDismiss
],
data() { data() {
return { return {
searchTxt: '', searchTxt: '',
@@ -123,16 +127,16 @@
}, },
onInvite() { onInvite() {
console.log(this.checkboxValue,'userIds.....') console.log(this.checkboxValue, 'userIds.....')
console.log(this.selectValue,'userIds.....') console.log(this.selectValue, 'userIds.....')
let userIds = [] let userIds = []
this.checkboxValue.filter(item=>{ this.checkboxValue.filter(item => {
if(!utils.inArray(item, this.selectValue)){ if (!utils.inArray(item, this.selectValue)) {
userIds.push(item) userIds.push(item)
} }
}) })
// console.log(userIds) // console.log(userIds)
inviteGroupUser(this.targetId, this.checkboxValue,userIds).then(res => { inviteGroupUser(this.targetId, this.checkboxValue, userIds).then(res => {
uni.navigateBack({ uni.navigateBack({
delta: 1, delta: 1,
animationType: 'pop-out', animationType: 'pop-out',

View File

@@ -3,7 +3,7 @@
<view class="reviewed"> <view class="reviewed">
<block v-if="pendings.length > 0"> <block v-if="pendings.length > 0">
<view class="reviewed-item" v-for="(item, index) in pendings" :key="index"> <view class="reviewed-item" v-for="(item, index) in pendings" :key="index">
<u-avatar class="avatar" <u-avatar class="avatar"
:src="JSON.parse(item.content.extra).portraitUrl || require('@/static/user/cover.png')" :src="JSON.parse(item.content.extra).portraitUrl || require('@/static/user/cover.png')"
shape="square" size="46" /> shape="square" size="46" />
<view style="flex:1;" v-if="item.content.operation == 'GroupPending'"> <view style="flex:1;" v-if="item.content.operation == 'GroupPending'">
@@ -34,9 +34,12 @@
} from "@/apis/interfaces/im.js" } from "@/apis/interfaces/im.js"
import im from '@/utils/im/message.js' import im from '@/utils/im/message.js'
import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index' import * as RongIMLib from '@/uni_modules/RongCloud-IMWrapper/js_sdk/index'
import onGroupDismiss from '@/utils/im/onGroupDismiss.js'
export default { export default {
mixins: [
onGroupDismiss
],
data() { data() {
return { return {
targetId: '', targetId: '',
@@ -93,7 +96,7 @@
console.log('code', code) console.log('code', code)
if (code == 0) { if (code == 0) {
uni.showToast({ uni.showToast({
title:err.message, title: err.message,
icon: 'none', icon: 'none',
mask: true, mask: true,
duration: 2000 duration: 2000
@@ -153,6 +156,7 @@
} }
} }
.no-lists { .no-lists {
padding-top: $padding * 5; padding-top: $padding * 5;
display: flex; display: flex;

View File

@@ -4,7 +4,12 @@
<script> <script>
import groupUserList from '../components/groupUserList' import groupUserList from '../components/groupUserList'
import onGroupDismiss from '@/utils/im/onGroupDismiss.js'
export default { export default {
mixins: [
onGroupDismiss
],
components: { components: {
groupUserList groupUserList
}, },

View File

@@ -57,24 +57,28 @@
// 好友申请数量 // 好友申请数量
this.checkNewFriendPending() this.checkNewFriendPending()
// 监听新的好友申请 // 监听新的好友申请
uni.$on('onContactNotification', () => { uni.$on('onNewContactConversation', this.checkNewFriendPending)
this.checkNewFriendPending()
})
}, },
onShow() { onShow() {
if (this.$store.state.token !== '') { if (this.$store.state.token !== '') {
this.getConversationList() this.getConversationList()
} }
uni.$on('onConnectionStatusChange', (status) => {
this.connection = status
})
// 监听新消息 // 监听新消息
uni.$on('onReceiveMessage', (msg) => { uni.$on('onReceiveMessage', (msg) => {
this.getConversationList() this.getConversationList()
}) })
// 监听网络状态变化
uni.$on('onConnectionStatusChange', (status) => {
this.connection = status
if (status == 0) {
this.getConversationList()
}
})
}, },
onHide() { onHide() {
// 页面隐藏的时候,不监听了,性能可能会好一点
uni.$off('onReceiveMessage') uni.$off('onReceiveMessage')
uni.$off('onConnectionStatusChange')
}, },
methods: { methods: {
checkNewFriendPending() { checkNewFriendPending() {

View File

@@ -150,7 +150,7 @@
} else { } else {
IMLib.insertIncomingMessage(1, targetId, targetId, sentStatus, messageContent, sentTime) IMLib.insertIncomingMessage(1, targetId, targetId, sentStatus, messageContent, sentTime)
} }
uni.$emit('onReceiveMessage', { uni.$emit('onReceiveMessage_' + this.targetId, {
targetId: this.targetId targetId: this.targetId
}) })
}, },

View File

@@ -60,6 +60,10 @@
}) })
// 获取消息列表 // 获取消息列表
this.getMessageList() this.getMessageList()
// 监听新消息
uni.$on('onReceiveMessage_' + this.targetId, (message) => {
this.getNewMessage()
})
// 监听消息已读状态 // 监听消息已读状态
uni.$on('onReadReceiptReceived', (data) => { uni.$on('onReadReceiptReceived', (data) => {
if (data.targetId == this.targetId) { if (data.targetId == this.targetId) {
@@ -72,14 +76,21 @@
}) })
} }
}) })
// 监听收到新消息,判断是否是当前会话,更新会话内容 uni.$on('onRecallMessage', (res) => {
uni.$on('onReceiveMessage', (msg) => { if (res.targetId == this.targetId) {
if (msg.targetId == this.targetId) { this.messages = this.messages.map(item => {
this.getNewMessage() if (res.messageId == item.messageId) {
return res
} else {
return item
}
})
} }
}) })
}, },
onUnload() { onUnload() {
uni.$off('onReceiveMessage_' + this.targetId)
uni.$off('onRecallMessage')
uni.$off('onReadReceiptReceived') uni.$off('onReadReceiptReceived')
}, },
methods: { methods: {

BIN
static/.DS_Store vendored

Binary file not shown.

View File

@@ -20,7 +20,28 @@ const onReceiveMessage = (message) => {
} }
}) })
im.setNotifyBadge() im.setNotifyBadge()
// 发布全局事件,有新消息,刷新会话列表
uni.$emit('onReceiveMessage', message) uni.$emit('onReceiveMessage', message)
// 这个是为了更新消息列表页的
uni.$emit('onReceiveMessage_' + message.targetId, message)
}
// 检测联系人信息,不存在的时候,从服务端获取
const checkContactExists = (message) => {
if (!store.getters.contactIsExist(message.targetId)) {
getUserInfo(message.targetId).then(res => {
store.dispatch('initContact', res)
}).catch(err => {
console.error('getUserInfo ERR', err)
})
}
if (!store.getters.contactIsExist(message.senderUserId)) {
getUserInfo(message.senderUserId).then(res => {
store.dispatch('initContact', res)
}).catch(err => {
console.error('getUserInfo ERR', err)
})
}
} }
// 允许通知的消息类型,触发更新消息列表操作,提示音 // 允许通知的消息类型,触发更新消息列表操作,提示音
@@ -32,10 +53,7 @@ const notifyMsgTypes = [
IMLib.ObjectName.Location, IMLib.ObjectName.Location,
IMLib.ObjectName.Voice, IMLib.ObjectName.Voice,
IMLib.ObjectName.HQVoice, IMLib.ObjectName.HQVoice,
IMLib.ObjectName.Sight, IMLib.ObjectName.Sight
IMLib.ObjectName.Text,
IMLib.ObjectName.Text,
IMLib.ObjectName.Text
] ]
const imLibListeners = () => { const imLibListeners = () => {
@@ -48,31 +66,19 @@ const imLibListeners = () => {
IMLib.addReceiveMessageListener((res) => { IMLib.addReceiveMessageListener((res) => {
const message = res.data.message const message = res.data.message
console.error('[收到消息]', message) console.error('[收到消息]', message)
checkContactExists(message)
if (utils.inArray(message.objectName, notifyMsgTypes)) { if (utils.inArray(message.objectName, notifyMsgTypes)) {
if (!store.getters.contactIsExist(message.targetId)) {
getUserInfo(message.targetId).then(res => {
store.dispatch('initContact', res)
}).catch(err => {
console.error('getUserInfo ERR', err)
})
}
if (!store.getters.contactIsExist(message.senderUserId)) {
getUserInfo(message.senderUserId).then(res => {
store.dispatch('initContact', res)
}).catch(err => {
console.error('getUserInfo ERR', err)
})
}
onReceiveMessage(message) onReceiveMessage(message)
} else if (message.objectName === IMLib.ObjectName.ProfileNotification) { } else if (message.objectName === IMLib.ObjectName.ProfileNotification) {
// 更新会话信息 // 更新联系人信息
store.dispatch('updateContact', JSON.parse(message.content.data)) store.dispatch('updateContact', JSON.parse(message.content.data))
// 调用完更新之后,删除这条消息 // 调用完更新之后,删除这条消息
IMLib.deleteMessagesByIds([message.messageId]) IMLib.deleteMessagesByIds([message.messageId])
} else if (message.objectName === IMLib.ObjectName.ContactNotification) { } else if (message.objectName === IMLib.ObjectName.ContactNotification) {
console.error('触发一个新好友的通知事件', message); // 触发一个新好友的通知事件,【会话列表,通讯录,新朋友】页面
// 触发一个新好友的通知事件 uni.$emit('onNewContactConversation', message)
uni.$emit('onContactNotification', message) uni.$emit('onNewContactFriends', message)
uni.$emit('onNewContactPendings', message)
} else if (message.objectName === IMLib.ObjectName.GroupNotification) { } else if (message.objectName === IMLib.ObjectName.GroupNotification) {
// 解散群 // 解散群
if (message.content.operation === 'Dismiss') { if (message.content.operation === 'Dismiss') {
@@ -80,8 +86,11 @@ const imLibListeners = () => {
false) false)
// 解散了就删了吧 // 解散了就删了吧
IMLib.removeConversation(message.conversationType, message.targetId) IMLib.removeConversation(message.conversationType, message.targetId)
uni.$emit('onGroupDismiss', message.targetId) // 发布群解散的消息
uni.$emit('onGroupDismiss')
uni.$emit('onGroupDismiss_' + message.targetId)
} }
// 触发刷新会话列表
uni.$emit('onReceiveMessage', message) uni.$emit('onReceiveMessage', message)
} }
}) })
@@ -103,12 +112,26 @@ const imLibListeners = () => {
IMLib.addReceiptRequestListener(({ IMLib.addReceiptRequestListener(({
data data
}) => { }) => {
console.error('onReceiptRequested', data);
uni.$emit('onReceiptRequest', data) uni.$emit('onReceiptRequest', data)
}) })
// 群消息已读的回执 // 群消息已读的回执
IMLib.addReceiptResponseListener((res) => { IMLib.addReceiptResponseListener(({
console.error('onReceiptResponse', res); data
}) => {
// 获取本地消息
IMLib.getMessageByUId(data.messageUId, ({
message
}) => {
const readers = Object.keys(data.users).length
const extra = JSON.stringify({
readers
})
// 在消息的扩展数据中,设置已读数量
IMLib.setMessageExtra(message.messageId, extra, (result) => {
message.extra = extra
uni.$emit('onReceiptResponse', message)
})
})
}) })
} }

View File

@@ -0,0 +1,16 @@
// 监听群解散的消息,直接跳转到会话列表页面
const onGroupDismiss = {
onLoad(e) {
uni.$once('onGroupDismiss_' + e.targetId, () => {
uni.showToast({
icon: 'none',
title: '当前群已解散'
})
uni.switchTab({
url: '/pages/im/index'
})
})
}
}
export default onGroupDismiss