小程序怎么导入sdk实现聊天功能
首先使用npm进行下载腾讯云的即时聊天sdk;然后在项目中进行引用并进行sdk初始化;再根据后台接口返回userid,usersig这两个参数判断当前登录人是谁;最后根据文档实现基础功能即可。
示例代码
wxml:
<scroll-view bindscroll="refresh" scroll-into-view="{{toview}}" style="height: {{scroll_height}}px;" upper-threshold="100" scroll-y="true" enable-back-to-top="true" class="message-list"> <!-- 每一行 --> <view class="row" wx:for="{{messages}}" wx:key="{{index}}" id="row_{{index}}"> <!-- 日期 --> <view class="datetime" wx:if="{{item.msgtime != ''}}">{{item.msgtime}}</view> <!-- 头像与内容文本 --> <view class="body" style="flex-flow: {{item.flow == 'in' ? 'row' : 'row-reverse'}}"> <view class="avatar-container"> <image wx:if="{{item.flow=='in'}}" class="avatar" src="{{friendavatarurl}}" /> <image wx:else class="avatar" src="{{userdata.avatarurl}}" /> </view> <!-- 画对话框 --> <view class="triangle" style="{{item.flow == 'out' ? 'right: 140rpx; background: #7ecb4b' : 'left: 140rpx;'}}"></view> <view class="content" style="{{item.flow == 'out' ? 'background: #7ecb4b' : ''}}"> <view wx:if="{{item.type === 'timtextelem'}}">{{item.payload.text}}</view> <image class="image-message" wx:elif="{{item.type === 'timimageelem'}}" src="{{item.payload.imageinfoarray[1].url}}" bindtap="previewimage" data-src="{{item.payload.imageinfoarray[1].url}}"></image> <view wx:elif="{{item.type === 'timsoundelem'}}" url="{{item.payload.url}}"> <view class="box" bindtap="openaudio" data-eventid="{{'13_'+index}}" data-time="{{item.payload.second}}" data-comkey="{{item.payload.url}}"> <image src="{{'13_'+index==audioindex?audiogif:audiopng}}" style="height:22px;width:22px" class="_image"></image> <view style="padding-left: 4px;" class="_div data-v-afeb3abc"> {{item.payload.second<1?1:item.payload.second}}s </view> </view> </view> </view> </view> </view></scroll-view><view class="reply" style="bottom:{{reply_height}}px;"> <view class="audio"> <image wx:if="{{opration==true}}" bindtap="audio" src="../image/audio.png"></image> <image wx:else bindtap="keyboard" src="../image/keyboard.png"></image> </view> <view class="opration-area"> <input bindfocus="bindfocus" wx:if="{{opration==true}}" type="text" bindinput="getcontent" value="{{content}}" /> <view wx:else class="voice-button {{touchbtn?'hoverbtn':''}}" bind:touchstart="startaudio" bind:touchend="ontouchend" bind:longpress="onlongpress" bind:touchmove="ontouchmove"> {{touchbtn?'松开 结束':'按住说话'}} </view> </view> <view class="{{sendbtn==true?'send':'sendactive'}}" bindtap="sendmsg">发送</view> <view class="add" bind:tap="moreclick"> <image class="more" src="../image/more.png"></image> </view> <!-- <view class="send" bindtap="sendimg">相册</view> <view class="send" bindtap="startaudio">开始</view> <view class="send" bindtap="endaudio">结束</view> --></view><view class="more_box" hidden="{{moreshow}}"> <view class="more_item" bindtap="sendimg"> <view class="img_box"> <image src="../image/picture.png"></image> </view> <view style="margin-top:10rpx;"> <text>相册</text> </view> </view></view>
js:
import tim from 'tim-wx-sdk';import cos from "cos-wx-sdk-v5";let options = { sdkappid: 0 // 接入时需要将0替换为您的即时通信 im 应用的 sdkappid};// 创建 sdk 实例,`tim.create()`方法对于同一个 `sdkappid` 只会返回同一份实例let tim = tim.create(options); // sdk 实例通常用 tim 表示// 设置 sdk 日志输出级别,详细分级请参见 setloglevel 接口的说明tim.setloglevel(1); // 普通级别,日志量较多,接入时建议使用// tim.setloglevel(1); // release 级别,sdk 输出关键信息,生产环境时建议使用// 注册 cos sdk 插件tim.registerplugin({ 'cos-wx-sdk': cos});const app = getapp()let recordermanager = wx.getrecordermanager();// 录音部分参数 小程序文档const recordoptions = { duration: 60000, // 录音的时长,单位 ms,最大值 600000(10 分钟) samplerate: 44100, // 采样率 numberofchannels: 1, // 录音通道数 encodebitrate: 192000, // 编码码率 format: 'aac' // 音频格式,选择此格式创建的音频消息,可以在即时通信 im 全平台(android、ios、微信小程序和web)互通};page({ data: { friendid: '', friendname: '', friendavatarurl: '', messages: [], // 消息集合 complete: 0, // 是否还有历史消息可以拉取,1 - 表示没有,0 - 表示有 content: '', // 输入框的文本值 lock: false, // 发送消息锁 true - 加锁状态 false - 解锁状态 scroll_height: wx.getsysteminfosync().windowheight - 54, reply_height: 0, moreshow: true, userdata: [], audiopng:"../image/audio-play.png", audiogif:"../image/audio-play.gif", audiostate:true, /** * 历史消息消息集合(结构如下): * nextreqmessageid 用于续拉,分页续拉时需传入该字段。 * iscompleted 表示是否已经拉完所有消息。 */ nextreqmessageid: "", iscompleted: "", isfirstgetlist: true, audiocontext: null, opration: true, touchbtn: false, recording: false, stopflag: false, cancelrecord: false, refreshtime: '', scrollloading: 0, audioindex:null, sendbtn:true }, onload: function (options) { // this.setdata({ friendid: options.friendid, friendname: options.friendname, friendavatarurl: options.friendavatarurl, conversationid: options.conversationid }) wx.setnavigationbartitle({ title: options.friendname }) var that = this var userdata = json.parse(wx.getstoragesync('userdata')) that.data.messages = [] // 清空历史消息 let audiocontext = wx.createinneraudiocontext() this.setdata({ userdata, audiocontext }) // 将某会话下所有未读消息已读上报 let promise = tim.setmessageread({ conversationid: options.conversationid }); promise.then(function (imresponse) { // 已读上报成功 }).catch(function (imerror) { // 已读上报失败 }); }, onshow: function () { let that = this; // 获取当前聊天的历史列表 that.getmessagelist(); that.scrolltobottom(); // 获取收到的单聊信息 let onmessagereceived = function (event) { // event.data - 存储 message 对象的数组 - [message] let msglist = that.data.messages handlerhistorymsgs(event.data, that) that.scrolltobottom(); }; tim.on(tim.event.message_received, onmessagereceived) // 监听录音结束 recordermanager.onstop(function (res) { if (that.data.recording) { if (that.data.cancelrecord) { wx.hidetoast() that.setdata({ cancelrecord: false }) } else { // 创建消息实例,接口返回的实例可以上屏 const message = tim.createaudiomessage({ to: that.data.friendid, conversationtype: tim.types.conv_c2c, payload: { file: res }, onprogress: function (event) { } }); // 发送消息 let promise = tim.sendmessage(message); promise.then(function (imresponse) { // 发送成功 that.addmessage(imresponse.data.message, that) }).catch(function (imerror) { // 发送失败 }); that.setdata({ recording: false }) } } else { wx.showtoast({ title: '说话时间太短', duration: 1000, image: '../image/err.png' }) } }); }, onunload: function () { }, /** * 获取消息列表 */ getmessagelist() { let that = this; let cb = tim.getmessagelist({ conversationid: conversationid,//会话列表传递过来的参数 count: 15 }) cb.then(function (imresponse) { const messagelist = imresponse.data.messagelist; // 消息列表。 const nextreqmessageid = imresponse.data.nextreqmessageid; // 用于续拉,分页续拉时需传入该字段。 const iscompleted = imresponse.data.iscompleted; // 表示是否已经拉完所有消息。 that.setdata({ nextreqmessageid: nextreqmessageid, iscompleted: iscompleted }) handlerhistorymsgs(messagelist, that); that.scrolltobottom(); }); }, /** * 获取文本的消息 */ getcontent: function (e) { if(e.detail.value ==""){ this.setdata({sendbtn:true}) }else{ this.setdata({sendbtn:false}) } console.log(e) var that = this; that.setdata({ content: e.detail.value }) }, /** * 发送消息 */ sendmsg: function (e) { if(this.data.content ==""){ wx.showtoast({ title: '请输入内容', duration: 1000, icon:'none' }) return } var that = this // 发送文本消息,web 端与小程序端相同 // 1. 创建消息实例,接口返回的实例可以上屏 let message = tim.createtextmessage({ to: this.data.friendid, conversationtype: tim.types.conv_c2c, payload: { text: this.data.content } }); // 2. 发送消息 let promise = tim.sendmessage(message); promise.then(function (imresponse) { // 发送成功 that.addmessage(imresponse.data.message, that) that.setdata({sendbtn:true}) }).catch(function (imerror) { // 发送失败 }); }, /** * 刷新文本消息 */ addmessage: function (msg, that) { var messages = that.data.messages; messages.push(msg); that.setdata({ messages: messages, content: '' // 清空输入框文本 }) that.scrolltobottom(); }, /** * 发送图片消息 */ sendimg() { let that = this; wx.chooseimage({ sourcetype: ['album'], // 从相册选择 count: 1, // 只选一张,目前 sdk 不支持一次发送多张图片 success: function (res) { // 2. 创建消息实例,接口返回的实例可以上屏 let message = tim.createimagemessage({ to: that.data.friendid, conversationtype: tim.types.conv_c2c, payload: { file: res }, onprogress: function (event) { } }); // 3. 发送图片 let promise = tim.sendmessage(message); promise.then(function (imresponse) { // 发送成功 that.addmessage(imresponse.data.message, that) }).catch(function (imerror) { // 发送失败 }); } }) }, scrolltobottom: function () { this.setdata({ toview: 'row_' + (this.data.messages.length - 1) }); }, previewimage(e) { let src = ''; wx.previewimage({ current: e.currenttarget.dataset.src, // 当前显示图片的http链接 urls: [e.currenttarget.dataset.src] }) }, // 录制语音 startaudio: function () { wx.showtoast({ title: '上滑取消发送', duration: 10000, image: '../image/cancel.png' }) this.setdata({ touchbtn: true }) if (this.data.stopflag) { return; } recordermanager.start(recordoptions); recordermanager.onerror(function (errmsg) { }); }, // # 利用长按判断录音是否太短 onlongpress() { this.setdata({ recording: true }) }, // 发送录音 ontouchend: function () { wx.hidetoast() let that = this; that.setdata({ touchbtn: false }) if (that.data.stopflag) { return; } if (that.data.recording) { recordermanager.stop(); } else { that.setdata({ stopflag: true }) settimeout(() => { recordermanager.stop(); that.setdata({ stopflag: false }) }, 400); } }, // 播放语音 openaudio(audio) { console.log(audio) let index = audio.currenttarget.dataset.eventid this.setdata({ audioindex:index // audiostate:false }) this.data.audiocontext.src = audio.currenttarget.dataset.comkey this.data.audiocontext.autoplay = true; this.data.audiocontext.play() this.data.audiocontext.onplay((res) => { }) this.data.audiocontext.onended(() => { wx.hidetoast() this.setdata({ audioindex:null }) console.log("语音结束了") }) this.data.audiocontext.onerror((res) => { }) }, // 上滑取消 ontouchmove(e) { if (e.touches[0].clienty < 520) { // # 取消发送 this.setdata({ cancelrecord: true }); wx.showtoast({ title: '松开,取消发送', duration: 10000, image: '../image/cancel.png' }) } else { // # 不取消 wx.hidetoast() wx.showtoast({ title: '上滑取消发送', duration: 10000, image: '../image/cancel.png' }) this.setdata({ cancelrecord: false }) } }, // 下拉加载聊天记录 refresh: function (e) { let that = this if (that.data.scrollloading == 1) { //防止多次触发 return false } if (e.detail.scrolltop < 1) { that.setdata({ scrollloading: 1 }) wx.showloading({ title: '加载中', }) settimeout(() => { let promise = tim.getmessagelist({ conversationid: that.data.conversationid, nextreqmessageid: that.data.nextreqmessageid, count: 15 }); promise.then(function (imresponse) { const newmessagelist = imresponse.data.messagelist; // 消息列表。 const nextreqmessageid = imresponse.data.nextreqmessageid; // 用于续拉,分页续拉时需传入该字段。 const iscompleted = imresponse.data.iscompleted; // 表示是否已经拉完所有消息。 that.setdata({ nextreqmessageid: nextreqmessageid, iscompleted: iscompleted, messages: newmessagelist.concat(that.data.messages) }) wx.hideloading() that.setdata({ scrollloading: 0 }) // handlerhistorymsgs(messagelist, that); }); }, 800); } // settimeout(function(){ // var date = new date(); // },300); }, // 切换 audio() { this.setdata({ opration: false }) }, keyboard() { this.setdata({ opration: true }) }, moreclick() { if (this.data.moreshow) { this.setdata({ moreshow: false, reply_height: 92, scroll_height: this.data.scroll_height - 92 }) } }, bindfocus() { this.setdata({ moreshow: true, reply_height: 0, scroll_height: wx.getsysteminfosync().windowheight - 54 }) }})/** * 处理历史消息 */function handlerhistorymsgs(result, that) { var historymsgs = that.data.messages; result.foreach(item => { historymsgs.push(item) }) // historymsgs.push(result[0]) that.setdata({ messages: historymsgs, }) // 将某会话下所有未读消息已读上报 let promise = tim.setmessageread({ conversationid: that.data.conversationid }); promise.then(function (imresponse) { // 已读上报成功 }).catch(function (imerror) { // 已读上报失败 });}
wxss:
/** 聊天窗口样式 * 54px为回复框高度,js同 *//*聊天记录*/page{ background: rgb(245, 245, 245);}.message-list { /*margin-bottom: 54px;*/ background: rgb(235, 235, 235);}/*单元行*/.row { display: flex; flex-direction: column; margin: 0 30rpx;}/*日期*/.datetime { font-size: 10px; padding: 10px 0; color: #999; text-align: center;}.send { font-size: 15px; /* padding-right: 10px; */ color: #999; text-align: center; height: 70%; border: 1px solid #e4dfdf; display: flex; align-items: center; justify-content: center; width: 90rpx; border-radius: 10rpx;}.sendactive { font-size: 15px; /* padding-right: 10px; */ color: #fff; text-align: center; height: 70%; border: 1px solid #05c15f; display: flex; align-items: center; justify-content: center; width: 90rpx; border-radius: 10rpx; background-color: #05c15f;}.audio { font-size: 15px; color: #999; text-align: center; padding-left: 10rpx;}.audio image { width: 50rpx; height: 50rpx;}.add { height: 70%; display: flex; align-items: center; justify-content: center; width: 90rpx;}.more { width: 50rpx; height: 50rpx;}/*主体*/.body { display: flex; flex-direction: row; align-items: flex-start; justify-content: flex-start; width: 100%; margin-top: 10px;}/*头像容器*/.body.avatar-container { width: 20%;}/*头像*/.body .avatar { width: 80rpx; height: 80rpx; border-radius: 50%; margin: 0 20rpx;}/*文本消息*/.body .content { font-size: 16px; background: #fff; border-radius: 5px; padding: 10px; line-height: 22px; margin-bottom: 10px; word-wrap: break-word; max-width: 300rpx;}/* 三角箭头 */.body .triangle { background: white; width: 20rpx; height: 20rpx; margin-top: 26rpx; transform: rotate(45deg); position: absolute;}/*图片消息*/.picture { width: 160px;}/*回复框*/.reply { display: flex; flex-direction: row; justify-content: flex-start; align-items: center; position: fixed; /* bottom: 0; */ width: 100%; height: 54px; border-top: 1px solid rgb(215, 215, 215); background: rgb(245, 245, 245);}.reply .voice-image { width: 25px; height: 25px; margin-left: 3%;}/*文本输入或语音录入*/.reply .opration-area { flex: 1; padding: 8px;}/*回复文本框*/.reply input { background: rgb(252, 252, 252); height: 36px; border: 1px solid rgb(221, 221, 221); border-radius: 6px; padding-left: 3px;}/*选取图片*/.reply .choose-image { width: 25px; height: 25px; margin-right: 3%;}/*按住说话button*/.voice-button { height: 36px; color: #818181; font-size: 14px; line-height: 36px; text-align: center; border: 1px solid #e4dfdf; border-radius: 10rpx;}/*悬浮提示框*/.hud-container { position: fixed; width: 150px; height: 150px; left: 50%; top: 50%; margin-left: -75px; margin-top: -75px;}/*背景层*/.hud-background { position: absolute; width: 100%; height: 100%; background: #999; opacity: 0.8; z-index: 11; border-radius: 10px;}/*悬浮框主体*/.hud-body { position: relative; width: 100%; height: 100%; z-index: 19; display: flex; flex-direction: column; justify-content: space-between; align-items: center;}/*图标*/.hud-body image { margin-top: 20px; width: 80px; height: 80px;}/*文字*/.hud-body .tip { color: #fff; text-align: center; width: 90%; line-height: 34px; margin: 0 auto; margin-bottom: 10px; width: 90%;}.hud-body .warning { background: #c33; border-radius: 5px;}.image-message { max-width: 100%; border-radius: 4rpx;}.box { display: flex; height: 40rpx; line-height: 40rpx;}.hoverbtn { background-color: rgb(226, 220, 220); color: #fff; border-radius: 10rpx;}.more_box {height: 138rpx;width: 100%;padding: 15rpx;display: flex;background: rgb(245, 245, 245);position: fixed;bottom: 0;}.more_item { text-align: center; height: 150rpx; font-size: 24rpx; margin-left: 26rpx}.img_box { width: 80rpx; height: 84rpx; background-color: #fff; display: flex; justify-content: center; align-items: center; border-radius: 10rpx;}.img_box image { width: 40rpx; height: 40rpx;}
推荐教程:《小程序开发》
以上就是小程序怎么导入sdk实现聊天功能的详细内容。