微信小程序实现聊天室
更新时间:2020年08月21日 10:23:28 作者:a_莲
这篇文章主要为大家详细介绍了微信小程序实现聊天室,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
本文实例为大家分享了微信小程序实现聊天室的具体代码,供大家参考,具体内容如下
正文:
<!-- <button bindtap='close'>关闭</button><button bindtap='open'>打开</button> --> <view wx:if='{{login}}' class='login_zz'></view> <button wx:if='{{login}}' class='login' bindgetuserinfo='userinfo' open-type="getUserInfo">登录</button> <view class='page_bg' wx:if='{{block}}' bindtap='hide_bg' /> <view class='btn_bg' wx:if='{{block}}'> <view wx:for="{{link_list}}" wx:key='index'> <button class="sp_tit" id='{{index}}' bindtap='list_item'>查看详情 {{item}} </button> </view> </view> <scroll-view class="history" scroll-y="true" scroll-with-animation scroll-top="{{scrollTop}}"> <block wx:key="{{index}}" wx:for="{{allContentList}}"> <block wx:if="{{item.is_my}}"> <view class='my_right new_txt'> <view class='time' wx:if='{{item.messageTime&&item.messageTime!=0}}'> {{item.messageTime}} </view> <view class='p_r page_r' style='margin-right: 25rpx;' wx:if='{{item.text}}'> <view class='new_txt'> <view class='new_txt_my'> <view class='arrow'> <em></em> <span></span> </view> <text decode="true">{{item.text}}</text> </view> </view> <image class='new_img' src='{{item.avatarUrl}}'></image> </view> <view class='p_r page_r' style='margin-right: 25rpx;' wx:if='{{item.audio}}' bindtap='my_audio_click' data-id='{{index}}'> <view class='new_txt_my_2' style=' width:{{item.length}}px'> <image class='my_audio' src='/images/yuyin_icon.png'></image> </view> <span class='_span'></span> <open-data class='new_img' type="userAvatarUrl"></open-data> </view> </view> </block> <!-- <view class='you_left' id='id_{{allContentList.length}}'> --> <block wx:if="{{item.is_ai&&item.is_ai!=''}}"> <view class='you_left' style='width:100%;' id='id_{{allContentList.length}}' wx:key="{{index}}"> <view class='time' wx:if='{{item.messageTime}}'> {{item.messageTime}} </view> <view class='p_r' style='margin-left: 20rpx;'> <image class='new_img' src='{{item.avatarUrl}}'></image> <view class='new_txt'> <view class='new_txt_ai'> <view class='arrow'> <em></em> <span></span> </view> <view class='ai_content'> <!-- <text wx:if='{{item.type=="1"}}' decode="true">{{item.text}}</text> --> <text decode="true">{{item.text}}</text> <!-- <image wx:if='{{item.type=="2"}}' style='width:160rpx;height:160rpx;' src='{{item.src}}'></image> --> </view> <view class='yes_problem_log' wx:if="{{item.yse_problem&&item.solve_show}}" style=''>感谢您的反馈,我们会再接再厉!</view> <view class='yes_problem_log' style='color:#32CF3C' wx:if="{{item.no_problem&&item.solve_show}}" bindtap='phone_click'>拨打人工客服</view> </view> </view> </view> </view> </block> </block> </scroll-view> <!-- 遮罩 --> <view class='zezhao' wx:if='{{cross}}' bindtap='add_icon_click' id='2'></view> <!-- 输入框 --> <view class='{{cross?"in_voice_icon":""}}'> <view class="sendmessage" style='bottom:{{input_bottom}}px'> <input type="text" style='{{focus?"border-bottom: 1px solid #88DD4B;":""}}' adjust-position='{{false}}' cursor-spacing='5' bindinput="bindKeyInput" value='{{inputValue}}' focus='{{focus}}' bindblur='no_focus' bindfocus="focus" confirm-type="done" placeholder="请输入您要咨询的问题" /> <button wx:if='{{if_send&&inputValue!=""}}' bindtap="submitTo" class='user_input_text'>发送</button> <image class='add_icon' bindtap='add_icon_click' id='1' wx:if='{{add&&!if_send&&inputValue==""}}' src='/images/jia_img.png'></image> <image class='add_icon' bindtap='add_icon_click' id='2' wx:if='{{cross}}' src='/images/audio/cross37.png'></image> </view> <view wx:if='{{cross}}' class='item' bindtap='phone_click'> <image class='img' src='/images/yuyin_icon.png'></image> <view class='text'>人工客服</view> </view> </view> <!-- <view class='zezhao' wx:if='{{add_icon_click}}' bindtap='add_icon_click'></view> --> <!-- <view class='in_voice_icon'> <view class="sendmessage_2"> <input type="text" bindinput="bindKeyInput" adjust-position='{{false}}' value='{{inputValue}}' focus='{{focus}}' bindfocus="focus" confirm-type="done" placeholder="" /> <image class='add_icon' bindtap='add_icon_click' src='/images/audio/cross37.png'></image> </view> <view class='item' bindtap='phone_click'> <image class='img' src='/images/yuyin_icon.png'></image> <view class='text'>人工客服</view> </view> </view> -->
page { background-color: #f2f2f2; height: 100%; padding: 0 auto; margin: 0 auto; } .login { z-index: 999; position: fixed; top: 300rpx; height: 100rpx; text-align: center; line-height: 100rpx; width: 400rpx; left: 50%; margin-left: -200rpx; background: white; } .Phone { top: 500rpx; width: 400rpx; } .login_zz { position: fixed; left: 0; top: 0; width: 100%; height: 100%; z-index: 998; background-color: rgba(0, 0, 0, 0.5); } 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; } .page_r { float: right; } .new_txt { min-width: 380rpx; width: 460rpx; word-break: break-all; } .new_txt_my { border-radius: 7rpx; background: #9fe75a; position: relative; right: 30rpx; 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 { 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; } .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; } .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 .item { position: relative; margin-top: 50rpx; margin-left: 50rpx; text-align: center; width: 140rpx; } .in_voice_icon .img { width: 80rpx; height: 80rpx; border-radius: 15rpx; } .in_voice_icon .text { font-size: 32rpx; margin-top: 20rpx; } .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 button { border: 1px solid white; width: 18%; height: 80rpx; background: #0c0; color: white; line-height: 80rpx; margin-top: 10rpx; font-size: 28rpx; } .hei { height: 20rpx; } .history { 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%; }
// pages/index/to_news/to_news.js var app = getApp(); var util = require("../../utils/util.js"); var socketOpen = false; var uuid = '', time_ = "1"; var recorder = wx.getRecorderManager(); const innerAudioContext = wx.createInnerAudioContext() //获取播放对象var frameBuffer_Data, session, SocketTask, string_base64; Page({ data: { login: false, listCustmerServiceBanner: [], indicatorDots: false, autoplay: false, interval: 5000, duration: 1000, user_input_text: '', //用户输入文字 inputValue: '', time: '', returnValue: '', if_send: false, add: true, cross: false, // is_my: true, text: '12432' allContentList: [{}, { is_ai: [] }], num: 0 }, // 页面加载 onLoad: function(e) { var that = this; if (wx, wx.getStorageSync('openid')) { this.setData({ login: false }) } else { this.setData({ login: true }) } let url = app.url + '/show.php' util.request(url, 'post', {}, '正在加载···', function(res) { for (var i = 0; i < res.data.length; i++) { console.log(i, res.data[i].iv, wx.getStorageSync('openid')) if (res.data[i].iv == wx.getStorageSync('openid')) { res.data[i].is_my = true } else { res.data[i].is_ai = true } } that.setData({ allContentList: res.data, inputValue: '' }) that.bottom() }) }, // 获取用户信息并且登录,获取openid userinfo: function(e) { var that = this; var nickName = JSON.parse(e.detail.rawData).nickName; var avatarUrl = JSON.parse(e.detail.rawData).avatarUrl; console.log('nickName:', nickName, 'avatarUrl:', avatarUrl) wx.setStorageSync('nickName', nickName) wx.setStorageSync('avatarUrl', avatarUrl) wx.login({ success: function(res) { let url = app.url + '/login.php' if (res.code) { util.request(url, 'post', { code: res.code }, '正在登录···', function(res) { console.log(res.data) if (res.data.openid) { var openid = res.data.openid; wx.setStorageSync('openid', openid); if (avatarUrl && openid) { wx.showToast({ title: '登录成功!', }) that.setData({ login: false }) } } }) } } }); }, // 页面加载完成 onReady: function() { var that = this; this.on_recorder(); this.bottom() }, // 提交文字 submitTo: function(e) { console.log('提交文字') let that = this; if (that.data.inputValue == "") { return; } var url = app.url + '/up_text.php' var data = { avatarUrl: wx.getStorageSync('avatarUrl'), iv: wx.getStorageSync('openid'), inputValue: that.data.inputValue, time: (new Date()).getTime() } console.log('提交文字data:', data) util.request(url, 'post', data, '', function(res) { // res.data = res.data.reverse(); for (var i = 0; i < res.data.length; i++) { console.log(i, res.data[i].iv, wx.getStorageSync('openid')) if (res.data[i].iv == wx.getStorageSync('openid')) { res.data[i].is_my = true } else { res.data[i].is_ai = true } } that.setData({ allContentList: res.data, inputValue: '' }) that.bottom() }, function(res) {}) }, // 点击加号 add_icon_click: function(e) { console.log(e.target.id) // 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) { console.log(e.detail.value) if (e.detail.value == "") { this.setData({ if_send: false, inputValue: e.detail.value }) } else { this.setData({ if_send: true, inputValue: e.detail.value }) } }, // 获取到焦点 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 }) } }, onHide: function() {}, // 获取hei的id节点然后屏幕焦点调转到这个节点 bottom: function() { var that = this; this.setData({ scrollTop: 100000 }) }, hide_bg: function() { this.setData({ block: false }) }, // 点击录音事件 my_audio_click: function(e) { console.log('my_audio_click执行了', e) var index = e.currentTarget.dataset.id; console.log('url地址', this.data.allContentList[index].audio); innerAudioContext.src = this.data.allContentList[index].audio innerAudioContext.seek(0); innerAudioContext.play(); }, // 手指点击录音 voice_ing_start: function() { var that = this; this.setData({ voice_ing_start_date: new Date().getTime(), //记录开始点击的时间 }) const options = { duration: 10000, //指定录音的时长,单位 ms sampleRate: 16000, //采样率 numberOfChannels: 1, //录音通道数 encodeBitRate: 24000, //编码码率 format: 'mp3', //音频格式,有效值 aac/mp3 frameSize: 12, //指定帧大小,单位 KB } recorder.start(options) //开始录音 this.animation = wx.createAnimation({ duration: 1200, }) //播放按钮动画 that.animation.scale(0.8, 0.8); //还原 that.setData({ spreakingAnimation: that.animation.export() }) }, // 录音监听事件 on_recorder: function() { recorder.onStart((res) => { console.log('开始录音'); }) recorder.onStop((res) => { console.log('停止录音,临时路径', res.tempFilePath); // _tempFilePath = res.tempFilePath; var x = new Date().getTime() - this.data.voice_ing_start_date if (x > 1000) { that.data.allContentList.push({ is_my: true, audio: res.tempFilePath, length: x / 1000 * 30 }); that.setData({ allContentList: that.data.allContentList }) } }) recorder.onFrameRecorded((res) => { var x = new Date().getTime() - this.data.voice_ing_start_date if (x > 1000) { console.log('onFrameRecorded res.frameBuffer', res.frameBuffer); string_base64 = wx.arrayBufferToBase64(res.frameBuffer) // console.log('string_base64--', wx.arrayBufferToBase64(string_base64)) if (res.isLastFrame) { var data = { audioType: 3, cmd: 1, type: 2, signType: 'BASE64', session: session, body: string_base64, } console.log('that.data.allContentList', that.data.allContentList) // 进行下一步操作 } else { var data = { cmd: 1, audioType: 2, type: 2, signType: 'BASE64', session: session, body: string_base64 } console.log('录音上传的data:', data) } } }) }, // 手指松开录音 voice_ing_end: function() { var that = this; that.setData({ voice_icon_click: false, animationData: {} }) this.animation = ""; var x = new Date().getTime() - this.data.voice_ing_start_date if (x < 1000) { console.log('录音停止,说话小于1秒!') wx.showModal({ title: '提示', content: '说话要大于1秒!', }) recorder.stop(); } else { // 录音停止,开始上传 recorder.stop(); } }, // 点击语音图片 voice_icon_click: function() { this.setData({ voice_icon_click: !this.data.voice_icon_click }) }, })
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
JSON在Javascript中的使用(eval和JSON.parse的区别)详细解析
这篇文章主要介绍了JSON在Javascript中的使用以及eval和JSON.parse的区别详细解析,本文对eval()和JSON.parse()的区别介绍的非常详细,需要的朋友可以参考下2017-09-09
最新评论