You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

335 lines
9.7 KiB

<template>
<view class="nine-content-001">
<view class="chat-body">
<view class="chat-body-main">
<view v-if="chatObject.haveHistory==0" class="chat-body-history">
没有更多消息了
</view>
<view v-else class="chat-body-history chat-body-history-have" @click="handleHistoryMessage()">
查看更多消息
</view>
<view class="chat-body-message">
<view v-for="(item, index) in messageList" :key="index">
<view class="chat-conversation" :class="item.fromId == userInfo.userId?'chat-conversation-mine':''">
<view class="chat-conversation-image">
<image class="chat-conversation-image-image" v-if="item.fromId != userInfo.userId" :src="getUserAvatar(item.fromId, item.avatar)"></image>
<image class="chat-conversation-image-image" v-else :src="userInfo.avatar || defaultAvatar"></image>
</view>
<view class="chat-conversation-text">
<view class="chat-conversation-text-time" v-if="item.sendType == 1 && item.fromId != userInfo.userId">{{getUserName(item.fromId, item.fromName)}}</view>
<view class="chat-conversation-text-time">{{formatTime(item.sendTime)}}</view>
<view class="chat-conversation-text-text nine-user-select">{{item.content}}</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="chat-footer">
<view class="chat-footer-send">
<view @click="handleVoice" class="chat-footer-send-voice">
<image class="chat-footer-send-image" :src="iconVoice"></image>
</view>
<view v-if="isVoice" @longpress="handleSay" class="chat-footer-send-say">
<span>按住 说话</span>
</view>
<view v-else class="chat-footer-send-input">
<input @confirm="handleSend" class="input" v-model="inputText" />
</view>
<view @click="handleEmoji" class="chat-footer-send-emoji">
<image class="chat-footer-send-image" :src="iconEmoji"></image>
</view>
<view v-if="inputText" @click="handleSend" class="chat-footer-send-button">
<span class="chat-footer-send-button-span">发送</span>
</view>
<view v-else @click="handleMore" class="chat-footer-send-more">
<image class="chat-footer-send-image" :src="iconMore"></image>
</view>
</view>
</view>
</view>
</template>
<script>
import { mapState } from 'vuex'
import store from '@/uni_modules/vrapile-im/store'
import { getChatKey } from '@/uni_modules/vrapile-im/utils/tiosocket';
// 外部需提供store用于获取用户信息,提供根据消息key查询用户历史消息接口
import storeOut from '@/store'
import { getMessageByChatKey } from '@/api/chat'
export default {
data() {
return {
userInfo: {},
chatObject: {},
messageList: [],
noHistory: true,
isVoice: false,
inputText: "",
// 消息唯一key
key: null,
// 用户默认图标
defaultAvatar: '/uni_modules/vrapile-im/static/image/yy.png',
// 消息铃铛图标
iconMessage: "/uni_modules/vrapile-im/static/image/message.png",
// 语音切换图标
iconVoice: "/uni_modules/vrapile-im/static/image/voice.png",
// 表情图标
iconEmoji: "/uni_modules/vrapile-im/static/image/emoji.png",
// 更多图标
iconMore: "/uni_modules/vrapile-im/static/image/more.png",
}
},
computed: {
...mapState({
websocketData: state => store.state.socket.websocketData
}),
getChatList() {
return store.state.chat.chatList;
},
getUserAvatar() {
return (userId, defaultAvatar) => {
return store.getters.getUserAvatar(userId, defaultAvatar);
}
},
getUserName() {
return (userId, defaultName) => {
return store.getters.getUserName(userId, defaultName);
}
}
},
onLoad(options){
this.userInfo = storeOut.state.user.userInfo;
if(!this.userInfo.userId){
this.navigateToLogin();
}
try{
this.key = options.data;
}catch(e){
this.switchTab("/uni_modules/vrapile-im/pages/home/chatHome");
}
},
// 下拉处理
onPullDownRefresh() {
if(this.chatObject.haveHistory==1){
this.handleHistoryMessage();
}
setTimeout(() => {
uni.stopPullDownRefresh();
}, 500);
},
onShow(){
for(let i=0; i < this.getChatList.length; i++){
if(this.getChatList[i]["key"] == this.key){
this.chatObject = this.getChatList[i];
uni.setNavigationBarTitle({
title: this.chatObject.name || "好友"
})
this.messageList = this.getChatList[i].messageList;
this.scrollToBottom();
if(this.messageList.length == 0 && this.chatObject.haveHistory==1){
this.handleHistoryMessage();
}else{
this.handleRead();
}
break;
}
}
},
// 监听消息
watch: {
websocketData: {
handler(newVal, oldval) {
if(newVal && newVal.length > 0
&& (newVal[newVal.length-1]["toId"] == this.userInfo.userId
|| newVal[newVal.length-1]["fromId"] == this.userInfo.userId)){
this.scrollToBottom();
this.handleRead();
}
},
immediate: true,
deep: true
}
},
methods: {
// 滚动到最新消息位置
scrollToBottom() {
setTimeout(() => {
uni.pageScrollTo({
scrollTop: 2000000,
duration : 10
})
}, 500);
},
// 语音点击事件
handleVoice() {
this.isVoice = !this.isVoice;
},
// 语音消息处理, 暂时先发送个提示
handleSay() {
let sendInfo = {
code: 2,
message: {
//消息文件类型 0-文本|1-图片|2-附件|3-语言|4-撤回
messageType: 0,
//聊天室id
toId: this.chatObject.id,
//消息发送人
fromId: this.userInfo.userId,
//消息发送人账号
fromName: this.userInfo.userName,
//消息内容
content: "您发送了一条语音消息",
//消息类型:0-私聊|1-群聊
sendType: this.chatObject.type,
//扩展消息
extend: null
},
};
uni.sendSocketMessage({
data: JSON.stringify(sendInfo)
})
},
// 表情消息处理, 暂时先发送个提示
handleEmoji() {
let sendInfo = {
code: 2,
message: {
//消息文件类型 0-文本|1-图片|2-附件|3-语言|4-撤回
messageType: 0,
//聊天室id
toId: this.chatObject.id,
//消息发送人
fromId: this.userInfo.userId,
//消息发送人账号
fromName: this.userInfo.userName,
//消息内容
content: "您发送了一个表情消息",
//消息类型:0-私聊|1-群聊
sendType: this.chatObject.type,
//扩展消息
extend: null
},
};
uni.sendSocketMessage({
data: JSON.stringify(sendInfo)
})
},
// 更多消息处理, 暂时先发送个提示
handleMore() {
let sendInfo = {
code: 2,
message: {
//消息文件类型 0-文本|1-图片|2-附件|3-语言|4-撤回
messageType: 0,
//聊天室id
toId: this.chatObject.id,
//消息发送人
fromId: this.userInfo.userId,
//消息发送人账号
fromName: this.userInfo.userName,
//消息内容
content: "您发送了一个更多的消息",
//消息类型:0-私聊|1-群聊
sendType: this.chatObject.type,
//扩展消息
extend: null
},
};
uni.sendSocketMessage({
data: JSON.stringify(sendInfo)
})
},
// 反馈已读
handleRead() {
let sendInfo = {
code: 3,
message: {
//聊天室id
toId: this.chatObject.id,
//消息发送人
userId: this.userInfo.userId,
//消息类型:0-私聊|1-群聊
sendType: this.chatObject.type,
},
};
uni.sendSocketMessage({
data: JSON.stringify(sendInfo)
})
store.commit('READ_MESSAGE', this.key);
store.commit('COUNT_MESSAGE');
},
// 发送消息
handleSend() {
if(!this.inputText){
return;
}
let sendInfo = {
code: 2,
message: {
//消息文件类型 0-文本|1-图片|2-附件|3-语言|4-撤回
messageType: 0,
//聊天室id
toId: this.chatObject.id,
//消息发送人
fromId: this.userInfo.userId,
//消息发送人账号
fromName: this.userInfo.userName,
//消息内容
content: this.inputText,
//消息类型:0-私聊|1-群聊
sendType: this.chatObject.type,
//扩展内容
extend: null
},
};
uni.sendSocketMessage({
data: JSON.stringify(sendInfo)
})
this.inputText = "";
},
// 获取历史消息
handleHistoryMessage(){
let limit = this.chatObject["messageList"].length + 10;
getMessageByChatKey({
type: this.chatObject.type,
key: this.chatObject["key"],
groupId: this.chatObject.id,
limit: limit
}).then(res => {
if(res.data.length > 0){
this.messageList = res.data.reverse();
this.chatObject["messageList"] = this.messageList;
let lastMessage = res.data[res.data.length-1];
this.chatObject["messageLast"] = lastMessage;
if(lastMessage["sendType"] == 0){
this.chatObject["messageShow"] = lastMessage["content"];
}else{
this.chatObject["messageShow"] = store.getters.getUserName(lastMessage["fromId"], lastMessage["fromName"]) + ": " + lastMessage["content"]
}
this.chatObject["messageTime"] = this.formatDate(lastMessage["sendTime"]);
}
if(res.data.length < limit){
this.chatObject["haveHistory"] = 0;
}
for(let i=0; i < this.getChatList.length; i++){
if(this.getChatList[i]["key"] == this.key){
this.$set(this.getChatList, i, this.chatObject)
break;
}
}
this.scrollToBottom();
});
}
}
}
</script>
<style scoped>
/* 重写外部nine-chat-friend-001.scss可实现样式改变 */
@import '/uni_modules/vrapile-im/static/style/nine-chat-friend-001.scss';
@import '/static/style/nine-chat-friend-001.scss';
</style>