vue2.0 web端使用腾讯IM,不太熟练,可自己进行重构
1:安装腾讯IM腾讯文档走起即时通信 IM 集成 SDK(Web & 小程序 & uni-app)-自实现 UI 集成方案-文档中心-腾讯云-腾讯云(1):基本配置走起2:登录到腾讯IM(可在用户登录账号后直接进行如下操作)3:监听IM的事件...............
·
我的ui页面
1:安装腾讯IM
腾讯文档走起即时通信 IM 集成 SDK(Web & 小程序 & uni-app)-自实现 UI 集成方案-文档中心-腾讯云-腾讯云
(1):基本配置走起
备注:下面两个为debug文件,应该可以不添加,添加的话请将第一个文件里面的内容修改,自行查看
//我实在main.js中引入的,下面的debug,自行去文档查看,把两个文件图放上面了
import {
SDKAPPID
} from './debug/GenerateTestUserSig'
// 引入tim
import TIM from "tim-js-sdk"
//由于我需要发送文件所以也用到了这个,如果你不需要可以不用引入和安装
import COS from "cos-js-sdk-v5"
import TIMUploadPlugin from 'tim-upload-plugin'
let options = {
SDKAppID: SDKAPPID //将0替换为及时通信IM应用的SDKAppID
}
let tim = TIM.create(options)
tim.setLogLevel(0)//设置SDK日志输出级别
tim.registerPlugin({ 'cos-js-sdk': COS, 'tim-upload-plugin': TIMUploadPlugin })//注册COS SDK插件
Vue.prototype.$tim = tim
2:在所需野蛮再次引入im相关数据(监听时能用到)
import TIM from "tim-js-sdk";
2-1:登录到腾讯IM(可在用户登录账号后直接进行如下操作)
// 从后端获取腾讯im的相关id以及userSig
userSig() {
api.getUserSig().then((res) => {
if (res.code == 200) {
this.$store.commit("SET_SIG", res.data);
this.timLogin(res.data.userId, res.data.userSig);
}
});
},
// 登录腾讯im
timLogin(userID, userSig) {
//注意,这里的userID必须为String类型,请自行转化
let promise = this.$tim.login({ userID: userID.toString(), userSig });
promise
.then((imResponse) => {
// 登录成功
if (imResponse.data.repeatLogin === true) {
// 标识账号已登录,本次登录操作为重复登录。v2.5.1 起支持
}
})
.catch(function (imError) {
console.warn("login error:", imError); // 登录失败的相关信息
});
},
3:监听IM的事件
// 监听im相关数据(自己将所需要监听的数据放到方法中在mounted中调用)
monitor() {
// 监听对方发过来的消息(这个监听会时时刻刻监听你正在沟通人的数据,里面是我自己对数据进行了处理,我这边使用的全部是自定义字段 event.data[0].payload.data全是自定义类型)
let onMessageReceived = (event) => {
let obj;
let payload = event.data[0].payload;
if (event.data[0].from !== this.chartId) return;
if (payload.data == "text") {
obj = {
mineMsg: false,
contactText: payload.description,
read: false,
id: event.data[0].ID,
time: event.data[0].clientTime,
avatar: event.data[0].avatar,
};
} else if (payload.data == "cv") {
obj = {
cv: true,
contactText: payload.description,
id: event.data[0].ID,
time: event.data[0].clientTime,
avatar: event.data[0].avatar,
};
} else if (payload.data == "connect") {
obj = {
connect: true,
contactText: payload.description,
phoneShow: true,
id: event.data[0].ID,
time: event.data[0].clientTime,
avatar: event.data[0].avatar,
};
} else if (payload.data == "img") {
obj = {
img: true,
contactText: payload.description,
id: event.data[0].ID,
time: event.data[0].clientTime,
avatar: event.data[0].avatar,
};
} else if (payload.data == "inte") {
obj = {
invite: true,
contactText: JSON.parse(item.payload.description),
id: event.data[0].ID,
time: event.data[0].clientTime,
avatar: event.data[0].avatar,
};
}
this.wordList.push(obj);
this.$nextTick(() => {
if (this.destory && this.chartId) {
//这里是我处理聊天框页面的滚动,只要有最新的数据过来就滚动条滚动到最底部
this.scrollEvent();
}
});
};
// 监听对方发过来的消息
this.$tim.on(TIM.EVENT.MESSAGE_RECEIVED, onMessageReceived);
let conversationList = (event) => {
this.chartList = event.data;
};
// 监听会话列表
this.$tim.on(TIM.EVENT.CONVERSATION_LIST_UPDATED, conversationList);
// 监听消息的已读,如果已读回执之后会进入
let onMessageReadByPeer = (event) => {
this.wordList.forEach((item) => {
if (item.mineMsg) {
item.read = true;
}
});
};
this.$tim.on(TIM.EVENT.MESSAGE_READ_BY_PEER, onMessageReadByPeer);
},
4.拉去会话列表
// 调取会话列表
readyList() {
const loading = this.$loading({
lock: true,
text: "加载中...",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
});
// 拉取会话列表
let promise = this.$tim.getConversationList();
promise
.then((imResponse) => {
let conversationList = imResponse.data.conversationList;
// console.log("拉取的会话列表", conversationList);
//这里有你所要的会话列表数据
this.chartList = conversationList;
//因为我这里需要特殊处理一下数据,所以进行了数据处理并赋值给一个新的数组(你用不到可以不用管)
let positionObj = conversationList.map((item) => {
if (item.lastMessage.payload.extension) {
if (JSON.parse(item.lastMessage.payload.extension).id) {
return {
position_id: JSON.parse(item.lastMessage.payload.extension).jopId,
user_id: JSON.parse(item.lastMessage.payload.extension).id,
im_user_id: item.userProfile.userID,
};
}
}
});
// console.log(positionObj)
let positionObjOne = positionObj.filter((item) => {
return item;
});
this.setConnect({ positions: positionObjOne });
loading.close();
})
.catch((imError) => {
console.log(imError);
loading.close();
});
},
5:点击聊天列表中的某一个人
// 点击联系人进行聊天
userClick(id, extension) {
// 判断是否包含扩展字段
if (extension) {
let extensionOne = JSON.parse(extension);
this.posiDetail(extensionOne.jopId);
this.extension = extensionOne;
}
this.chartId = id;
this.scrollEvent();
this.concatShow = true;
this.getSayList({ conversationID: `C2C${id}`, count: 15 });
// 将某会话下所有未读消息已读上报
let promise = this.$tim.setMessageRead({ conversationID: `C2C${id}` });
promise
.then(function (imResponse) {
// 已读上报成功,指定 ID 的会话的 unreadCount 属性值被置为0
})
.catch(function (imError) {
// 已读上报失败
console.warn("setMessageRead error:", imError);
});
},
5-1.拉取与某个人的会话列表
// 拉取某个人的会话数据
//options里面的内容为{ conversationID: `C2C${id}`, count: 15 }
getSayList(options) {
// 打开某个会话时,第一次拉取消息列表,注意!第一次拉取时不要传入 nextReqMessageID
let promise = this.$tim.getMessageList(options);
promise.then((imResponse) => {
let messageList = imResponse.data.messageList; // 消息列表。
// console.log("聊天列表", messageList);
// 获取最后一个聊天内容并将扩展字段赋值给data中的extension
if (messageList[messageList.length - 1].payload.extension) {
this.extension = JSON.parse(
messageList[messageList.length - 1].payload.extension
);
}
//在这里进行数据处理item.payload.data全是自己自定义的聊天类型
let wordList = messageList.map((item) => {
if (item.from == this.userId && item.payload.data == "text") {
return {
mineMsg: true,
contactText: item.payload.description,
read: item.isPeerRead ? true : false,
id: item.ID,
time: item.clientTime,
avatar: item.avatar,
};
} else if (item.payload.data == "cv") {
return {
cv: true,
contactText: item.payload.description,
id: item.ID,
time: item.clientTime,
avatar: item.avatar,
};
} else if (item.from == this.userId && item.payload.data == "connect") {
return {
connect: true,
contactText: item.payload.description,
phoneShow: false,
id: item.ID,
time: item.clientTime,
avatar: item.avatar,
};
} else if (item.from !== this.userId && item.payload.data == "text") {
return {
mineMsg: false,
contactText: item.payload.description,
read: false,
id: item.ID,
time: item.clientTime,
avatar: item.avatar,
};
} else if (item.from !== this.userId && item.payload.data == "connect") {
return {
connect: true,
contactText: item.payload.description,
phoneShow: true,
id: item.ID,
time: item.clientTime,
avatar: item.avatar,
};
} else if (item.payload.data == "inte") {
return {
invite: true,
contactText: JSON.parse(item.payload.description),
id: item.ID,
time: item.clientTime,
avatar: item.avatar,
};
} else if (item.payload.data == "cvText") {
return {
mineMsg: true,
contactText: "附件简历已发出",
read: item.isPeerRead ? true : false,
time: item.clientTime,
id: item.ID,
avatar: item.avatar,
};
}
});
let wordListOne = wordList.filter((item) => {
return item;
});
//从这里往下是处理对话框滚动条的js
if (this.concatShow) {
this.wordList = wordListOne;
this.scrollEvent();
} else {
for (let i = wordListOne.length - 1; i >= 0; i--) {
this.wordList.unshift(wordListOne[i]);
}
this.$nextTick(() => {
let msg = document.getElementsByClassName("chart-rightr-item")[0]; // 获取对象
msg.scrollTop = msg.scrollHeight - this.scrollHeight; // 滚动高度
});
}
// console.log(this.wordList);
//这个地方是用来处理获取上一页内容的数据
this.nextReqMessageID = imResponse.data.nextReqMessageID; // 用于续拉,分页续拉时需传入该字段。
this.isCompleted = imResponse.data.isCompleted; // 表示是否已经拉完所有消息。isCompleted 为 true 时,nextReqMessageID 为 ""。
});
},
6.发送消息
// im发送自定义消息 payload--->对应下面方法中的参数传递进来
sendSay(payload) {
// 发送文本消息,Web 端与小程序端相同
// 1. 创建消息实例,接口返回的实例可以上屏
let message = this.$tim.createCustomMessage({
to: this.chartId.toString(),
conversationType: TIM.TYPES.CONV_C2C,
payload,
});
// 2. 发送消息
let promise = this.$tim.sendMessage(message);
promise
.then((imResponse) => {
// console.log("发送消息", imResponse);
// 将某会话下所有未读消息已读上报
let promiseOne = this.$tim.setMessageRead({
conversationID: `C2C${this.chartId}`,
});
promiseOne
.then(function (imResponse) {
// 已读上报成功,指定 ID 的会话的 unreadCount 属性值被置为0
})
.catch(function (imError) {
// 已读上报失败
console.warn("setMessageRead error:", imError);
});
// 发送成功
let obj;
let payload = imResponse.data.message.payload;
let message = imResponse.data.message;
if (payload.data == "text") {
obj = {
mineMsg: true,
contactText: payload.description,
read: false,
time: message.clientTime,
id: message.ID,
avatar: message.avatar,
};
} else if (payload.data == "cv") {
obj = {
cv: true,
contactText: payload.description,
time: message.clientTime,
id: message.ID,
avatar: message.avatar,
};
} else if (payload.data == "connect") {
obj = {
connect: true,
contactText: payload.description,
time: message.clientTime,
phoneShow: false,
id: message.ID,
avatar: message.avatar,
};
} else if (payload.data == "cvText") {
obj = {
mineMsg: true,
contactText: "附件简历已发出",
read: false,
time: message.clientTime,
id: message.ID,
avatar: message.avatar,
};
}
this.wordList.push(obj);
this.scrollEvent();
})
.catch(function (imError) {
// 发送失败
console.warn("sendMessage error:", imError);
});
},
//其中一个发送消息的方法
cvClickOne() {
this.sendSay({
data: "connect", //自定义字段,获取消息列表以及会话列表根据这个进行判断展示
description: "已拒绝发送简历",//消息内容
extension: JSON.stringify(this.extension),//其他自定义字段类型,必须是字符串,可根据自己项目需求进行填写
});
//调用滚动条滚动到底部的方法
this.scrollEvent();
},
7.控制会话框滚动条滚动到底部
// 控制滚动条滚动到底部
scrollEvent() {
// 自动滚动到底部
this.$nextTick(() => {
let msg = document.getElementsByClassName("chart-rightr-item")[0]; // 获取对象
msg.scrollTop = msg.scrollHeight + 10; // 滚动高度
});
},
8.监听滚动条的高度,滚动到顶部吼拉去聊天数据
// 监听滚动条的高度,滚动到顶部后拉取聊天数据
scrollEventSay(e) {
if (!this.chartId) return;
this.scrollHeight = e.srcElement.scrollHeight;
if (e.srcElement.scrollTop == 0 && !this.isCompleted) {
this.concatShow = false;
this.getSayList({
conversationID: `C2C${this.chartId}`,
//拉取上一页聊天数据必传nextReqMessageID,在拉取会话列表中有提到
nextReqMessageID: this.nextReqMessageID,
count: 15,
});
}
},
9.我写的对话框(仅供参考css我就不贴出来了)
<div class="chart-rightr-item one" @scroll="scrollEventSay">
<div v-for="(item, index) in wordList" :key="item.id">
<!-- 时间 -->
<div class="word-time flex-center font-normal" v-show="index == 0">
{{ $util.dateFormat(item.time * 1000) }}
</div>
<!-- index不为第一个切两条消息相差5分钟才显示这个时间 -->
<div class="word-time flex-center font-normal" v-if="index !== 0">
{{
item.time - wordList[index - 1].time > 5 * 60
? $util.dateFormat(item.time * 1000)
: ""
}}
</div>
<!-- 对方的 -->
<div class="word row-center" v-if="item.mineMsg == false">
<img :src="item.avatar ? item.avatar : avatar" alt="" />
<!-- 因为文本中可能包含表情包,所以得借助方法解析对方的文本 -->
<div
class="flex-center"
style="word-break: break-all"
v-html="emoji.decoder.decode(item.contactText)"
></div>
</div>
<!-- 对方发送的电话邀请交换-->
<div class="el-word-phone row-center" v-if="item.phoneShow">
<img :src="item.avatar ? item.avatar : avatar" alt="" />
<div class="word-phone-div font-normal">
<div>我想和你交换联系方式 您是否同意</div>
<div class="word-phone-button row">
<div class="pointer" @click="sendPhoneOne">拒绝</div>
<div class="text-blue pointer" @click="sendPhone">同意</div>
</div>
</div>
</div>
<!-- 对方发送的面试邀请-->
<div class="el-word-phone row-center" v-if="item.invite">
<img :src="item.avatar ? item.avatar : avatar" alt="" />
<div class="el-word-phone-div-text font-normal">
<div class="row">
<img :src="item.avatar ? item.avatar : avatar" alt="" />
<span v-if="posiObj && posiObj.ent"
>{{ posiObj.ent.ent_name }}给你发出的面试邀请,点击查看</span
>
</div>
<div
class="word-phone-button-text text-blue pointer"
@click="checkInviteClick(item.contactText)"
>
立即查看
</div>
</div>
</div>
<!-- 交换联系方式,交换简历 -->
<div
class="exchange flex-center font-normal text-main"
v-if="item.connect && item.phoneShow == false"
>
{{ item.contactText }}
</div>
<!-- 对方发送的电话邀请交换-->
<div class="el-word-phone row-center" v-if="item.cv">
<img :src="item.avatar ? item.avatar : avatar" alt="" />
<div class="word-phone-div font-normal">
<div>我想获取你的简历 您是否同意</div>
<div class="word-phone-button row">
<div class="pointer" @click="cvClickOne">拒绝</div>
<div class="text-blue pointer" @click="cvClick">同意</div>
</div>
</div>
</div>
<!-- 我的 -->
<div class="word-my row" v-if="item.mineMsg">
<div
class="have-read flex-center text-white"
:class="item.read == false ? 'read-false' : ''"
>
{{ item.read ? "已读" : "未读" }}
</div>
<div class="row-center word-my-center">
<div
class="text-white bg-blue flex-center"
v-html="emoji.decoder.decode(item.contactText)"
></div>
<img :src="item.avatar ? item.avatar : avatar" alt="" />
</div>
</div>
</div>
</div>
更多推荐
已为社区贡献2条内容
所有评论(0)