|
|
|
@ -9,10 +9,10 @@ |
|
|
|
<view v-for="(msgInfo, idx) in chat.messages" :key="idx"> |
|
|
|
<chat-message-item :ref="'message'+msgInfo.id" v-if="idx >= showMinIdx" |
|
|
|
:headImage="headImage(msgInfo)" @call="onRtCall(msgInfo)" :showName="showName(msgInfo)" |
|
|
|
@recall="onRecallMessage" @delete="onDeleteMessage" @copy="onCopyMessage" |
|
|
|
@longPressHead="onLongPressHead(msgInfo)" @download="onDownloadFile" |
|
|
|
@audioStateChange="onAudioStateChange" :id="'chat-item-' + idx" :msgInfo="msgInfo" |
|
|
|
:groupMembers="groupMembers"> |
|
|
|
@resend="onResendMessage" @recall="onRecallMessage" @delete="onDeleteMessage" |
|
|
|
@copy="onCopyMessage" @longPressHead="onLongPressHead(msgInfo)" |
|
|
|
@download="onDownloadFile" @audioStateChange="onAudioStateChange" |
|
|
|
:id="'chat-item-' + idx" :msgInfo="msgInfo" :groupMembers="groupMembers"> |
|
|
|
</chat-message-item> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
@ -167,15 +167,24 @@ export default { |
|
|
|
return; |
|
|
|
} |
|
|
|
let msgInfo = { |
|
|
|
tmpId: this.generateId(), |
|
|
|
content: JSON.stringify(data), |
|
|
|
type: this.$enums.MESSAGE_TYPE.AUDIO, |
|
|
|
receipt: this.isReceipt |
|
|
|
} |
|
|
|
// 填充对方id |
|
|
|
this.fillTargetId(msgInfo, this.chat.targetId); |
|
|
|
// 防止发送期间用户切换会话导致串扰 |
|
|
|
const chat = this.chat; |
|
|
|
// 消息回显 |
|
|
|
let tmpMessage = this.buildTmpMessage(msgInfo); |
|
|
|
this.chatStore.insertMessage(tmpMessage, chat); |
|
|
|
this.moveChatToTop(); |
|
|
|
this.sendMessageRequest(msgInfo).then((m) => { |
|
|
|
m.selfSend = true; |
|
|
|
this.chatStore.insertMessage(m, this.chat); |
|
|
|
// 更新消息 |
|
|
|
tmpMessage.id = m.id; |
|
|
|
tmpMessage.status = m.status; |
|
|
|
this.chatStore.insertMessage(tmpMessage, chat); |
|
|
|
// 会话置顶 |
|
|
|
this.moveChatToTop(); |
|
|
|
// 滚动到底部 |
|
|
|
@ -299,10 +308,11 @@ export default { |
|
|
|
let receiptText = this.isReceipt ? "【回执消息】" : ""; |
|
|
|
let atText = this.createAtText(); |
|
|
|
let msgInfo = { |
|
|
|
tmpId: this.generateId(), |
|
|
|
content: receiptText + sendText + atText, |
|
|
|
atUserIds: this.atUserIds, |
|
|
|
receipt: this.isReceipt, |
|
|
|
type: 0 |
|
|
|
type: this.$enums.MESSAGE_TYPE.TEXT |
|
|
|
} |
|
|
|
// 清空@成员和回执标记 |
|
|
|
this.atUserIds = []; |
|
|
|
@ -311,15 +321,24 @@ export default { |
|
|
|
this.fillTargetId(msgInfo, this.chat.targetId); |
|
|
|
// 防止发送期间用户切换会话导致串扰 |
|
|
|
const chat = this.chat; |
|
|
|
// 回显消息 |
|
|
|
let tmpMessage = this.buildTmpMessage(msgInfo); |
|
|
|
this.chatStore.insertMessage(tmpMessage, chat); |
|
|
|
this.moveChatToTop(); |
|
|
|
|
|
|
|
this.sendMessageRequest(msgInfo).then((m) => { |
|
|
|
m.selfSend = true; |
|
|
|
this.chatStore.insertMessage(m, chat); |
|
|
|
// 会话置顶 |
|
|
|
this.moveChatToTop(); |
|
|
|
}).finally(() => { |
|
|
|
// 滚动到底部 |
|
|
|
this.scrollToBottom(); |
|
|
|
}); |
|
|
|
// 更新消息 |
|
|
|
tmpMessage = JSON.parse(JSON.stringify(tmpMessage)); |
|
|
|
tmpMessage.id = m.id; |
|
|
|
tmpMessage.status = m.status; |
|
|
|
tmpMessage.content = m.content; |
|
|
|
this.chatStore.insertMessage(tmpMessage, chat); |
|
|
|
}).catch(() => { |
|
|
|
// 更新消息 |
|
|
|
tmpMessage = JSON.parse(JSON.stringify(tmpMessage)); |
|
|
|
tmpMessage.status = this.$enums.MESSAGE_STATUS.FAILED; |
|
|
|
this.chatStore.insertMessage(tmpMessage, chat); |
|
|
|
}) |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
@ -410,7 +429,6 @@ export default { |
|
|
|
thumbUrl: file.path |
|
|
|
} |
|
|
|
let msgInfo = { |
|
|
|
id: 0, |
|
|
|
tmpId: this.generateId(), |
|
|
|
fileId: file.uid, |
|
|
|
sendId: this.mine.id, |
|
|
|
@ -419,8 +437,7 @@ export default { |
|
|
|
selfSend: true, |
|
|
|
type: this.$enums.MESSAGE_TYPE.IMAGE, |
|
|
|
readedCount: 0, |
|
|
|
loadStatus: "loading", |
|
|
|
status: this.$enums.MESSAGE_STATUS.UNSEND |
|
|
|
status: this.$enums.MESSAGE_STATUS.SENDING |
|
|
|
} |
|
|
|
// 填充对方id |
|
|
|
this.fillTargetId(msgInfo, this.chat.targetId); |
|
|
|
@ -431,8 +448,16 @@ export default { |
|
|
|
// 借助file对象保存 |
|
|
|
file.msgInfo = msgInfo; |
|
|
|
file.chat = this.chat; |
|
|
|
// 滚到最低部 |
|
|
|
this.scrollToBottom(); |
|
|
|
// 更新图片宽高 |
|
|
|
let chat = this.chat; |
|
|
|
this.getImageSize(file).then(size => { |
|
|
|
msgInfo = JSON.parse(JSON.stringify(msgInfo)) |
|
|
|
data.width = size.width; |
|
|
|
data.height = size.height; |
|
|
|
msgInfo.content = JSON.stringify(data) |
|
|
|
this.chatStore.insertMessage(msgInfo, chat); |
|
|
|
this.scrollToBottom(); |
|
|
|
}) |
|
|
|
return true; |
|
|
|
}, |
|
|
|
onUploadImageSuccess(file, res) { |
|
|
|
@ -440,15 +465,15 @@ export default { |
|
|
|
msgInfo.content = JSON.stringify(res.data); |
|
|
|
msgInfo.receipt = this.isReceipt |
|
|
|
this.sendMessageRequest(msgInfo).then((m) => { |
|
|
|
msgInfo.loadStatus = 'ok'; |
|
|
|
msgInfo.id = m.id; |
|
|
|
msgInfo.status = m.status; |
|
|
|
this.isReceipt = false; |
|
|
|
this.chatStore.insertMessage(msgInfo, file.chat); |
|
|
|
}) |
|
|
|
}, |
|
|
|
onUploadImageFail(file, err) { |
|
|
|
let msgInfo = JSON.parse(JSON.stringify(file.msgInfo)); |
|
|
|
msgInfo.loadStatus = 'fail'; |
|
|
|
msgInfo.status = this.$enums.MESSAGE_STATUS.FAILED; |
|
|
|
this.chatStore.insertMessage(msgInfo, file.chat); |
|
|
|
}, |
|
|
|
onUploadFileBefore(file) { |
|
|
|
@ -463,7 +488,6 @@ export default { |
|
|
|
url: file.path |
|
|
|
} |
|
|
|
let msgInfo = { |
|
|
|
id: 0, |
|
|
|
tmpId: this.generateId(), |
|
|
|
sendId: this.mine.id, |
|
|
|
content: JSON.stringify(data), |
|
|
|
@ -471,8 +495,7 @@ export default { |
|
|
|
selfSend: true, |
|
|
|
type: this.$enums.MESSAGE_TYPE.FILE, |
|
|
|
readedCount: 0, |
|
|
|
loadStatus: "loading", |
|
|
|
status: this.$enums.MESSAGE_STATUS.UNSEND |
|
|
|
status: this.$enums.MESSAGE_STATUS.SENDING |
|
|
|
} |
|
|
|
// 填充对方id |
|
|
|
this.fillTargetId(msgInfo, this.chat.targetId); |
|
|
|
@ -483,8 +506,6 @@ export default { |
|
|
|
// 借助file对象保存 |
|
|
|
file.msgInfo = msgInfo; |
|
|
|
file.chat = this.chat; |
|
|
|
// 滚到最低部 |
|
|
|
this.scrollToBottom(); |
|
|
|
return true; |
|
|
|
}, |
|
|
|
onUploadFileSuccess(file, res) { |
|
|
|
@ -497,17 +518,48 @@ export default { |
|
|
|
msgInfo.content = JSON.stringify(data); |
|
|
|
msgInfo.receipt = this.isReceipt |
|
|
|
this.sendMessageRequest(msgInfo).then((m) => { |
|
|
|
msgInfo.loadStatus = 'ok'; |
|
|
|
msgInfo.id = m.id; |
|
|
|
msgInfo.status = m.status; |
|
|
|
this.isReceipt = false; |
|
|
|
this.chatStore.insertMessage(msgInfo, file.chat); |
|
|
|
}) |
|
|
|
}, |
|
|
|
onUploadFileFail(file, res) { |
|
|
|
let msgInfo = JSON.parse(JSON.stringify(file.msgInfo)); |
|
|
|
msgInfo.loadStatus = 'fail'; |
|
|
|
msgInfo.status = this.$enums.MESSAGE_STATUS.FAILED; |
|
|
|
this.chatStore.insertMessage(msgInfo, file.chat); |
|
|
|
}, |
|
|
|
onResendMessage(msgInfo) { |
|
|
|
if (msgInfo.type != this.$enums.MESSAGE_TYPE.TEXT) { |
|
|
|
uni.showToast({ |
|
|
|
title: "该消息不支持自动重新发送,建议手动重新发送", |
|
|
|
icon: "none" |
|
|
|
}) |
|
|
|
return; |
|
|
|
} |
|
|
|
// 防止发送期间用户切换会话导致串扰 |
|
|
|
const chat = this.chat; |
|
|
|
// 删除旧消息 |
|
|
|
this.chatStore.deleteMessage(msgInfo, chat); |
|
|
|
// 重新发送 |
|
|
|
msgInfo.temId = this.generateId(); |
|
|
|
let tmpMessage = this.buildTmpMessage(msgInfo); |
|
|
|
this.chatStore.insertMessage(tmpMessage, chat); |
|
|
|
this.moveChatToTop(); |
|
|
|
this.sendMessageRequest(msgInfo).then(m => { |
|
|
|
// 更新消息 |
|
|
|
tmpMessage = JSON.parse(JSON.stringify(tmpMessage)); |
|
|
|
tmpMessage.id = m.id; |
|
|
|
tmpMessage.status = m.status; |
|
|
|
tmpMessage.content = m.content; |
|
|
|
this.chatStore.insertMessage(tmpMessage, chat); |
|
|
|
}).catch(() => { |
|
|
|
// 更新消息 |
|
|
|
tmpMessage = JSON.parse(JSON.stringify(tmpMessage)); |
|
|
|
tmpMessage.status = this.$enums.MESSAGE_STATUS.FAILED; |
|
|
|
this.chatStore.insertMessage(tmpMessage, chat); |
|
|
|
}) |
|
|
|
}, |
|
|
|
onDeleteMessage(msgInfo) { |
|
|
|
uni.showModal({ |
|
|
|
title: '删除消息', |
|
|
|
@ -594,7 +646,9 @@ export default { |
|
|
|
// #endif |
|
|
|
// #ifdef H5 |
|
|
|
// 防止滚动条定格在顶部,不能一直往上滚,h5采用scroll-top定位 |
|
|
|
this.holdingScrollBar(this.scrollViewHeight); |
|
|
|
if (uni.getSystemInfoSync().platform == 'ios') { |
|
|
|
this.holdingScrollBar(this.scrollViewHeight); |
|
|
|
} |
|
|
|
// #endif |
|
|
|
// 多展示20条信息 |
|
|
|
this.showMinIdx = this.showMinIdx > 20 ? this.showMinIdx - 20 : 0; |
|
|
|
@ -875,6 +929,30 @@ export default { |
|
|
|
} |
|
|
|
this.chatStore.insertMessage(msgInfo, this.chat); |
|
|
|
}, |
|
|
|
buildTmpMessage(msgInfo) { |
|
|
|
let message = JSON.parse(JSON.stringify(msgInfo)); |
|
|
|
message.sendId = this.mine.id; |
|
|
|
message.sendTime = new Date().getTime(); |
|
|
|
message.status = this.$enums.MESSAGE_STATUS.SENDING; |
|
|
|
message.selfSend = true; |
|
|
|
if (this.isGroup) { |
|
|
|
message.readedCount = 0; |
|
|
|
} |
|
|
|
return message; |
|
|
|
}, |
|
|
|
getImageSize(file) { |
|
|
|
return new Promise((resolve) => { |
|
|
|
uni.getImageInfo({ |
|
|
|
src: file.path, |
|
|
|
success: (res) => { |
|
|
|
resolve(res); |
|
|
|
}, |
|
|
|
fail: (err) => { |
|
|
|
console.error('获取图片信息失败', err); |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
}, |
|
|
|
generateId() { |
|
|
|
// 生成临时id |
|
|
|
return String(new Date().getTime()) + String(Math.floor(Math.random() * 1000)); |
|
|
|
@ -944,7 +1022,7 @@ export default { |
|
|
|
if (newSize > oldSize && oldSize > 0) { |
|
|
|
let lastMessage = this.chat.messages[newSize - 1]; |
|
|
|
if (this.$msgType.isNormal(lastMessage.type)) { |
|
|
|
if (this.isInBottom) { |
|
|
|
if (this.isInBottom || lastMessage.selfSend) { |
|
|
|
// 收到消息,则滚动至底部 |
|
|
|
this.scrollToBottom(); |
|
|
|
} else { |
|
|
|
|