相关文章:
1.小程序聊天群,发送语音,文字,图片。
2.微信小程序集成腾讯IM,实现实时音视频通话,1V1聊天
3.云开发微信小程序聊天群
4.接入网易云信IM即时通讯的微信小程序聊天室
5.微信小程序聊天功能 WebSocket 实现发送文字,图片,语音以及WebSocket 常见问题解决方案
6.[微信小程序]聊天对话(文本,图片)的功能(完整代码附效果图)
效果图:
首先确保小程序基础库版本 2.2.1 或以上、及开发者工具 1.02.1808300 或以上。(才能支撑npm)
操作步骤:
1、打开cmd ,进入项目的根目录,初始化 npm。
初始化之后,能做小程序根目录看到一个package.json 的文件,就证明初始化成功,
2、在小程序项目根目录执行:
// IM 小程序 SDK
npm install tim-wx-sdk --save
// 发送图片、文件等消息需要的 COS SDK
npm install cos-wx-sdk-v5 --save
3、点击开发者工具右上角详情,勾选使用npm模块,不校验和合法域名。
4、打开小程序左上角,工具,点击构建npm,完成构建出来这些东西就算完成了
小程序实现代码:
js
// doc_yl/test/test.js
import TIM from 'tim-wx-sdk';
import COS from "cos-wx-sdk-v5";
var roomID, userID, to_user, userSig, to_user_head, conversationID;
// var userID = "user5";
// let to_user = 'user4';
// var userSig = "eJwtzEELgjAYxvHvsmshb5tbKnQICkwsMneoo7AVb2atTSuIvntDPT6-B-5fIvMyeGlLEkIDINN*o9L3Fs-Yc*e05ePhVF0Zg4oksxCAUQ5UDE*LjfbKI8bmsWB0UP0xaL0LCCOAsYEXX3WYvnMrD9212S2zonjE5famK3t6WgRcyf2xm2wyUad0vSC-P9irMVY_";
// "userID=user5&to_user=user4&userSig=eJwtzEELgjAYxvHvsmshb5tbKnQICkwsMneoo7AVb2atTSuIvntDPT6-B-5fIvMyeGlLEkIDINN*o9L3Fs-Yc*e05ePhVF0Zg4oksxCAUQ5UDE*LjfbKI8bmsWB0UP0xaL0LCCOAsYEXX3WYvnMrD9212S2zonjE5famK3t6WgRcyf2xm2wyUad0vSC-P9irMVY_&to_user_head=xxx.png&roomID=1002"
// var userID = "user4";
// let to_user = 'user5';
// var userSig = "eJwtzF0LwiAYhuH-4ulivTldOugwdpAQfUDQ2ZhWL5GY2lpE-z3ZdvhcNzxfclSHvDOeVITmQGbDRm1sxAsO-ArGsykEfW*cQ02qBQMoKAdajiXiwyTloiiWkksY1fQOffISmIDJAl7Ta4u2Cc8zFa4TsMs228zDXIFf39qmlqc67lVnS9V-*HtFfn*5vzDK";
// var conversationID = "C2C" + to_user;
let that, pageImResponse;
const sdkAppID = 1400325026;
let tim
Page({
onLoad: function (options) {
that = this;
let timOptions = {
SDKAppID: sdkAppID // 接入时需要将0替换为您的即时通信 IM 应用的 SDKAppID
};
tim = TIM.create(timOptions); // SDK 实例通常用 tim 表示
tim.setLogLevel(0);
tim.registerPlugin({
'cos-wx-sdk': COS
});
userID = options.userID
to_user = options.to_user
userSig = options.userSig
to_user_head = options.to_user_head
roomID = options.roomID
conversationID = "C2C" + to_user;
console.log('11111111111111111111111111',to_user)
this.setData({
im_id: userID
})
that.im_on();
let promise = tim.login({
userID,
userSig
});
promise.then(function (imResponse) {
pageImResponse = imResponse;
console.log('------登录成功', pageImResponse); // 登录成功
}).catch(function (imError) {
console.warn('------login error:', imError); // 登录失败的相关信息
});
},
data: {
vvvv: false,
im_id: userID,
inputValue: "",
trtcConfig: {
sdkAppID: sdkAppID, // 开通实时音视频服务创建应用后分配的 SDKAppID
userID, // 用户 ID,可以由您的帐号系统指定
userSig, // 身份签名,相当于登录密码的作用
template: 'grid', // 画面排版模式
},
add: true
},
// 获取到焦点
focus: function (e) {
var that = this;
console.log(e.detail.height)
this.setData({
focus: true,
add: true,
cross: false,
input_bottom: e.detail.height
})
},
// 失去焦点
no_focus: function (e) {
if (this.data.cross) {
this.setData({
focus: false,
input_bottom: 240,
})
} else {
this.setData({
focus: false,
input_bottom: 0
})
}
},
// 点击加号
add_icon_click: function (e) {
// e.target.id == 1 点击加号 ==2 点击 X
if (e.target.id == 2) {
this.setData({
add: true,
cross: false,
input_bottom: 0
})
} else if (e.target.id == 1) {
this.setData({
add: false,
cross: true,
input_bottom: 240
})
}
},
// 输入框
bindKeyInput: function (e) {
if (e.detail.value == "") {
this.setData({
if_send: false,
inputValue: e.detail.value
})
} else {
this.setData({
if_send: true,
inputValue: e.detail.value
})
}
},
// 获取消息列表
getList() {
// 打开某个会话时,第一次拉取消息列表
console.log('----------222222222打开某个会话时,第一次拉取消息列表')
tim.getMessageList({
conversationID: conversationID,
count: 15
}).then(function (imResponse) {
console.log('----------222222222', imResponse)
const messageList = imResponse.data.messageList; // 消息列表。
const nextReqMessageID = imResponse.data.nextReqMessageID; // 用于续拉,分页续拉时需传入该字段。
const isCompleted = imResponse.data.isCompleted; // 表示是否已经拉完所有消息。
that.setData({
messageList
})
that.bottom()
// 下拉查看更多消息
// let promise = tim.getMessageList({ conversationID: conversationID, nextReqMessageID, count: 15 });
// promise.then(function (imResponse) {
// const messageList = imResponse.data.messageList; // 消息列表。
// const nextReqMessageID = imResponse.data.nextReqMessageID; // 用于续拉,分页续拉时需传入该字段。
// const isCompleted = imResponse.data.isCompleted; // 表示是否已经拉完所有消息。
// });
});
},
// 发送视频通话
sendv() {
that.setData({
vvvv: true
}, () => {
let trtcRoomContext = this.selectComponent('#trtcroom')
let EVENT = trtcRoomContext.EVENT
if (trtcRoomContext) {
// 发布本地音频流和视频流
trtcRoomContext.publishLocalVideo()
trtcRoomContext.publishLocalAudio()
// 监听远端用户的视频流的变更事件
trtcRoomContext.on(EVENT.REMOTE_VIDEO_ADD, (event) => {
console.error('--------监听远端用户的视频流的变更事件:', event)
// 订阅(即播放)远端用户的视频流
let v_userID = event.data.userID
let streamType = event.data.streamType // 'main' or 'aux'
trtcRoomContext.subscribeRemoteVideo({
userID: v_userID,
streamType: streamType
})
})
// 监听退出房间
trtcRoomContext.on(EVENT.LOCAL_LEAVE, (event) => {
console.error('--------监听退出房间:', event)
that.setData({
vvvv: false,
cross: false,
add: true,
input_bottom: 0
})
})
// 监听远端用户的音频流的变更事件
trtcRoomContext.on(EVENT.REMOTE_AUDIO_ADD, (event) => {
console.error('--------监听远端用户的音频流的变更事件:', event)
// 订阅(即播放)远端用户的音频流
let userID = event.data.userID
trtcRoomContext.subscribeRemoteAudio(userID)
})
// 进入房间
trtcRoomContext.enterRoom({
roomID: roomID
}).catch((res) => {
console.error('--------room joinRoom 进房失败:', res)
that.setData({
vvvv: false
})
})
}
})
},
onUnload(){
let promise = tim.logout();
promise.then(function(imResponse) {
console.log(imResponse.data); // 登出成功
}).catch(function(imError) {
console.warn('logout error:', imError);
});
// tim=
},
// 监听IM
im_on() {
console.log('监听-------------------------')
// 监听事件,例如:
tim.on(TIM.EVENT.SDK_READY, function (event) {
// 收到离线消息和会话列表同步完毕通知,接入侧可以调用 sendMessage 等需要鉴权的接口
// event.name - TIM.EVENT.SDK_READY
console.log('收到离线消息和会话列表同步完毕通知,接入侧可以调用')
that.getList()
});
tim.on(TIM.EVENT.MESSAGE_RECEIVED, function (event) {
// 收到推送的单聊、群聊、群提示、群系统通知的新消息,可通过遍历 event.data 获取消息列表数据并渲染到页面
// event.name - TIM.EVENT.MESSAGE_RECEIVED
// event.data - 存储 Message 对象的数组 - [Message]
console.log('.----------收到推送的单聊、群聊、群提示、群系统通知的新消息', event.data)
that.setMessageList(event.data[0])
});
tim.on(TIM.EVENT.MESSAGE_REVOKED, function (event) {
// 收到消息被撤回的通知
// event.name - TIM.EVENT.MESSAGE_REVOKED
// event.data - 存储 Message 对象的数组 - [Message] - 每个 Message 对象的 isRevoked 属性值为 true
});
tim.on(TIM.EVENT.CONVERSATION_LIST_UPDATED, function (event) {
// 收到会话列表更新通知,可通过遍历 event.data 获取会话列表数据并渲染到页面
// event.name - TIM.EVENT.CONVERSATION_LIST_UPDATED
// event.data - 存储 Conversation 对象的数组 - [Conversation]
});
tim.on(TIM.EVENT.GROUP_LIST_UPDATED, function (event) {
// 收到群组列表更新通知,可通过遍历 event.data 获取群组列表数据并渲染到页面
// event.name - TIM.EVENT.GROUP_LIST_UPDATED
// event.data - 存储 Group 对象的数组 - [Group]
});
tim.on(TIM.EVENT.GROUP_SYSTEM_NOTICE_RECEIVED, function (event) {
// 收到新的群系统通知
// event.name - TIM.EVENT.GROUP_SYSTEM_NOTICE_RECEIVED
// event.data.type - 群系统通知的类型,详情请参见 GroupSystemNoticePayload 的 operationType 枚举值说明
// event.data.message - Message 对象,可将 event.data.message.content 渲染到到页面
});
tim.on(TIM.EVENT.PROFILE_UPDATED, function (event) {
// 收到自己或好友的资料变更通知
// event.name - TIM.EVENT.PROFILE_UPDATED
// event.data - 存储 Profile 对象的数组 - [Profile]
});
tim.on(TIM.EVENT.BLACKLIST_UPDATED, function (event) {
// 收到黑名单列表更新通知
// event.name - TIM.EVENT.BLACKLIST_UPDATED
// event.data - 存储 userID 的数组 - [userID]
});
tim.on(TIM.EVENT.ERROR, function (event) {
// 收到 SDK 发生错误通知,可以获取错误码和错误信息
// event.name - TIM.EVENT.ERROR
// event.data.code - 错误码
// event.data.message - 错误信息
});
tim.on(TIM.EVENT.SDK_NOT_READY, function (event) {
// 收到 SDK 进入 not ready 状态通知,此时 SDK 无法正常工作
// event.name - TIM.EVENT.SDK_NOT_READY
});
tim.on(TIM.EVENT.KICKED_OUT, function (event) {
// 收到被踢下线通知
// event.name - TIM.EVENT.KICKED_OUT
// event.data.type - 被踢下线的原因,例如:
// - TIM.TYPES.KICKED_OUT_MULT_ACCOUNT 多实例登录被踢
// - TIM.TYPES.KICKED_OUT_MULT_DEVICE 多终端登录被踢
// - TIM.TYPES.KICKED_OUT_USERSIG_EXPIRED 签名过期被踢
});
},
// 发送图片
sendImg() {
// 小程序端发送图片
// 1. 选择图片
wx.chooseImage({
sourceType: ['album'], // 从相册选择
count: 1, // 只选一张,目前 SDK 不支持一次发送多张图片
success: function (res) {
// 2. 创建消息实例,接口返回的实例可以上屏
let message = tim.createImageMessage({
to: to_user,
conversationType: TIM.TYPES.CONV_C2C,
payload: {
file: res
},
onProgress: function (event) {
console.log('-------file uploading:', event)
}
});
// 3. 发送图片
let promise = tim.sendMessage(message);
promise.then(function (imResponse) {
// 发送成功
console.log('----------发送图片:', imResponse);
that.setMessageList(imResponse.data.message)
that.setData({
cross: false,
add: true,
input_bottom: 0
})
}).catch(function (imError) {
// 发送失败
console.warn('---------sendMessage error:', imError);
});
}
})
},
// 添加聊天列表数据
setMessageList(obj) {
console.log('添加聊天列表数据')
let messageList = that.data.messageList;
messageList.push(obj)
that.setData({
messageList
})
that.bottom();
},
// 发送文字消息
sendMessage() {
console.log('----------', pageImResponse)
if (pageImResponse) {
// 1. 创建消息实例,接口返回的实例可以上屏
let pageMessage = tim.createTextMessage({
to: to_user,
conversationType: TIM.TYPES.CONV_C2C,
payload: {
text: that.data.inputValue
}
});
// 2. 发送消息
tim.sendMessage(pageMessage).then(function (msg) {
// 发送成功
console.log('-----------------------111', msg);
that.setMessageList(msg.data.message)
that.setData({
add: true,
if_send: false,
inputValue: ''
})
}).catch(function (imError) {
// 发送失败
console.log('-----------------------222', imError);
});
} else {
setTimeout(() => {
this.sendMessage()
}, 500)
}
},
onReady: function () {
},
// 获取hei的id节点然后屏幕焦点调转到这个节点
bottom: function () {
var that = this;
this.setData({
scrollTop: 100000
})
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
wxml
{{item.payload.text}}
{{item.payload.text}}
发送图片
视频聊天
css
page {
background-color: #f2f2f2;
height: 100%;
padding: 0 auto;
margin: 0 auto;
}
swiper {
height: 180rpx;
}
swiper swiper-item .slide-image {
width: 100%;
height: 180rpx;
}
.jia_img {
height: 80rpx;
width: 90rpx;
}
.time {
text-align: center;
padding: 5rpx 20rpx 5rpx 20rpx;
border-radius: 10rpx;
display: block;
height: 38rpx;
line-height: 38rpx;
position: relative;
margin: 0 auto;
margin-bottom: 20rpx;
width: 90rpx;
color: white;
font-size: 26rpx;
background-color: #dedede;
}
.tab {
bottom: 120rpx;
}
.tab_1 {
position: fixed;
bottom: 50rpx;
width: 200rpx;
font-size: 26rpx;
left: 50%;
margin-left: -45rpx;
height: 100rpx;
}
.tab_2 {
right: 30rpx;
position: fixed;
}
/* 聊天 */
.my_right {
float: right;
margin-top: 30rpx;
position: relative;
}
.my_audio {
height: 60rpx;
width: 60rpx;
z-index: 2;
position: relative;
top: 10rpx;
left: 20rpx;
}
.you_left {
margin-top: 30rpx;
float: left;
position: relative;
padding-left: 5rpx;
}
.new_img {
width: 85rpx;
height: 85rpx;
overflow: hidden;
position: absolute;
right: 30rpx;
}
.page_r {
float: right;
}
.new_txt {
min-width: 380rpx;
width: 460rpx;
word-break: break-all;
}
.pay_img{
max-width: 400rpx;
}
.new_txt_my {
border-radius: 7rpx;
background: #9fe75a;
position: relative;
right: 120rpx;
min-height: 50rpx;
padding: 17rpx 30rpx 17rpx 30rpx;
float: right;
border: 1px solid #d0d0d0;
}
.new_txt_my .arrow {
position: absolute;
z-index: 2;
width: 40rpx;
right: -38rpx;
}
.new_txt_my .arrow em {
position: absolute;
border-style: solid;
border-width: 15rpx;
border-color: transparent transparent transparent #d0d0d0;
top: 1rpx;
}
.new_txt_my .arrow span {
position: absolute;
top: 5rpx;
border-style: solid;
border-width: 15rpx;
border-color: transparent transparent transparent #9fe75a;
}
.new_txt_my_2 {
word-break: break-all;
border-radius: 7rpx;
background: #9fe75a;
min-width: 330rpx;
max-width: 530rpx;
padding: 17rpx 30rpx 17rpx 30rpx;
float: right;
}
.new_txt_ai {
max-width: 460rpx;
border-radius: 7rpx;
left: 20rpx;
background-color: #fff;
position: relative;
border: 1px solid #d0d0d0;
float: left;
}
.new_txt_ai .arrow {
position: relative;
width: 40rpx;
left: -30rpx;
}
.new_txt_ai .arrow em {
position: absolute;
border-style: solid;
border-width: 15rpx;
top: 20rpx;
border-color: transparent #d0d0d0 transparent transparent;
}
.new_txt_ai .arrow span {
position: absolute;
top: 20rpx;
border-style: solid;
border-width: 15rpx;
border-color: transparent #fff transparent transparent;
left: 2rpx;
}
.ai_content {
word-break: break-all;
padding: 17rpx 30rpx 17rpx 30rpx;
/* max-width: */
}
.sanjiao {
top: 25rpx;
position: relative;
width: 0px;
height: 0px;
border-width: 15rpx;
border-style: solid;
}
.my {
border-color: transparent transparent transparent #9fe75a;
}
.you {
border-color: transparent #fff transparent transparent;
}
._span {
border-color: #fff transparent transparent;
top: -17px;
}
.is_ai_btn {
border-radius: 0 0 7px 7px;
border-top: 1px solid #d0d0d0;
background: white;
position: relative;
bottom: 0;
left: 0;
width: 100%;
height: 80rpx;
line-height: 80rpx;
display: flex;
flex-direction: row;
text-align: center;
}
.is_ai_btn view {
width: 50%;
}
.is_ai_btn image {
width: 32rpx;
position: relative;
top: 4rpx;
height: 32rpx;
}
.is_ai_btn .two {
border-left: 1px solid #d0d0d0;
}
.yes_problem_log {
border-top: 1px solid #d0d0d0;
height: 80rpx;
text-align: center;
line-height: 80rpx;
}
.voice_icon {
width: 60rpx;
height: 60rpx;
margin: 0 auto;
padding: 10rpx 10rpx 10rpx 10rpx;
}
.add_icon {
width: 70rpx;
height: 70rpx;
margin: 0 auto;
padding: 20rpx 10rpx 10rpx 15rpx;
/* transform: rotate(45deg); */
}
.voice_ing {
width: 90%;
height: 75rpx;
line-height: 85rpx;
text-align: center;
border-radius: 15rpx;
border: 1px solid #d0d0d0;
}
.zezhao {
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 2;
width: 100%;
background: rgba(0, 0, 0, 0.5);
}
.in_voice_icon {
z-index: 3;
left: 0;
bottom: 0;
width: 100%;
position: absolute;
height: 500rpx;
background: #f8f8f8;
}
.in_voice_icon .item1 {
position: relative;
left: 20%;
margin-top: 180rpx;
text-align: center;
width: 120rpx;
}
.p_r{
display: flex;
flex-direction: row;
}
.video{
position: fixed;
top: 0;
bottom: 0;
}
.in_voice_icon .item2 {
position: relative;
left: 50%;
margin-top: 180rpx;
text-align: center;
width: 120rpx;
}
.in_voice_icon .img {
width: 120rpx;
height: 120rpx;
border-radius: 15rpx;
}
.in_voice_icon .text {
font-size: 32rpx;
margin-top: 20rpx;
background: white;
width: 200rpx;
margin-left: -40rpx;
border-radius: 15rpx;
height: 80rpx;
line-height: 80rpx;
}
.sendmessage {
width: 100%;
z-index: 2;
display: flex;
position: fixed;
bottom: 0px;
background-color: #f8f8f8;
flex-direction: row;
height: 100rpx;
}
.sendmessage input {
width: 78%;
height: 80rpx;
line-height: 80rpx;
font-size: 28rpx;
margin-top: 10rpx;
margin-left: 20rpx;
border-bottom: 1px solid #d0d0d0;
padding-left: 20rpx;
}
.sendmessage .user_input_text {
border: 1px solid white;
width: 130rpx;
height: 80rpx;
background: #0c0;
color: white;
line-height: 80rpx;
margin-top: 10rpx;
text-align: center;
font-size: 28rpx;
}
.hei {
height: 20rpx;
}
.history {
/* height: 73%; */
height: 88%;
display: flex;
font-size: 14px;
line-height: 50rpx;
position: relative;
top: 20rpx;
}
.icno_kf {
position: fixed;
bottom: 160rpx;
margin: 0 auto;
text-align: center;
left: 50%;
margin-left: -40rpx;
width: 100rpx;
height: 100rpx;
border-radius: 50%;
}