jasonDev
jasonDev
  • 发布:2021-05-27 10:13
  • 更新:2021-05-30 14:54
  • 阅读:679

为什么这个聊天模板,收到消息后,不能刷新界面呢?

分类:uni-app
// 进入这个页面的时候创建websocket连接【整个页面随时使用】  
            connectSocketInit() {  
                let _this = this;  
                // 创建一个this.socketTask对象【发送、接收、关闭socket都由这个对象操作】  
                _this.socketTask = uni.connectSocket({  
                    // 【非常重要】必须确保你的服务器是成功的,如果是手机测试千万别使用ws://127.0.0.1:9099【特别容易犯的错误】  
                    url: 'ws://www.bjcn-tech.com:30190/vom/api/websocket/' + this.groupId, // 31',//'后台的地址', **例如:ws: '192.168.10.101:8080'**  
                    success(data) {  
                        console.log("websocket连接成功");  
                    },  
                    fail(data){  
                        console.log("websocket连接失败");  
                    }  
                });  

                // 消息的发送和接收必须在正常连接打开中,才能发送或接收【否则会失败】  
                _this.socketTask.onOpen((res) => {  
                    console.log("WebSocket连接正常打开中...!");  
                    _this.is_open_socket = true;  

                    // 注:只有连接正常打开中 ,才能正常成功发送消息  
                    /* this.socketTask.send({  
                        data:  '{"type":"2","userid":"118","groupid":"31","mp3":"uni-app发送一条消息222"}',  
                        async success() {  
                            console.log("消息发送成功");  
                        },  
                    }); */  
                    // 注:只有连接正常打开中 ,才能正常收到消息  
                    _this.socketTask.onMessage((res) => {  
                        console.log("收到服务器内容:" + res.data);  
                        if (JSON.parse(res.data).type == "2") {  
                            console.log("收到服务器内容:" + res.data);  
                            console.log("收到服务器内容:" + typeof(JSON.parse(res.data).type));  
                            console.log("收到服务器内容:" + JSON.parse(res.data).userid + '****' + JSON.parse(res.data).username);  
                            console.log('in this.socketTask.onMessage((res)')  
                            var nowDate = new Date();  
                            console.log('长度为'+_this.msgList.length);  
                            for(var i=0;i<_this.msgList.length;i++){                              
                                console.log(' this.msgList=  '+  _this.msgList[i].msg.id  
                                +'username='+ _this.msgList[i].msg.userinfo.username);   
                                }  
                            let lastid = _this.msgList[_this.msgList.length - 1].msg.id;  
                            debugger;  
                            console.log('in  this.socketTask.onMessage lastid=' + lastid)  
                            lastid++;  
2021-05-27 10:13 负责人:无 分享
已邀请:
jasonDev

jasonDev (作者) - 努力

_this.msgList.length 这里的长度,总是和 页面初始化时候的长度不一样

回梦無痕

回梦無痕 - 暂停服务

这里长连接代码应该是你自己写的,既然用了箭头函数,应该就不用 定义_this 了,直接用this,_this这个指向可能有问题。
另外我使用lastid是因为模板里面是本地创建消息,实际中应该直接取服务器返回的消息ID的。

  • jasonDev (作者)

    服务器返回的消息ID?服务器一张表里存了好几个群的聊天记录,返回的消息id有用吗?我一开始是用this,效果达不到(不能滚动到最新的记录),就改用了_this

    2021-05-27 11:24

  • 回梦無痕

    回复 jasonDev: 无论表里面存多少群信息也一样的,因为每个消息都有一个唯一的消息ID(如果你的没有,是数据库设计有问题)。ID作用就是vue渲染和给滚动跳转到最新消息用的,步骤是,服务器返回数据,渲染到页面,然后再根据消息的ID跳转到列表最底。

    2021-05-27 14:29

  • jasonDev (作者)

    回复 回梦無痕: 谢谢回复,可是做后台的很强硬,说“显示最新消息到相应的位置 非得用服务端的id 这个说法很奇怪”。不要这个id,安卓端能显示最新消息到底端吗?

    2021-05-27 15:20

  • 回梦無痕

    回复 jasonDev: 你们的后台是坑货,如果以后增加需求,要撤回/删除消息,你没消息的ID传给后台,后台怎么知道要撤回哪条消息,这个ID又不是什么敏感信息,估计就单纯他不想改而已。

    如果后台的确不给ID,那么需要自己创建ID。原理也一样的,后台返回最新消息时候,获取上次的ID,自增1,再赋值给最新消息,然后渲染到页面,然后修改scroll-into-view为最新ID。

    2021-05-28 14:43

  • jasonDev (作者)

    回复 回梦無痕: 目前就是这么做的啊。可是收到最新的消息的时候,去msgList里拿上次的id,总是不正确。似乎onMessage里 的 msgList和 一开始加载时候的msgList,不一样啊

    2021-05-28 15:40

  • 回梦無痕

    回复 jasonDev: 我猜还是_this的指向问题,直接用this吧。这个滚动到底的方案我是在商用项目上实现过的。测试过程和上线至今,客户没有反馈有问题的

    2021-05-28 16:01

  • jasonDev (作者)

    回复 回梦無痕: 方便留给qq吗?帮我改下代码,有偿也行

    2021-05-30 07:01

jasonDev

jasonDev (作者) - 努力

getMsgList() {  
                //let list = [{type:"system",msg:{id:0,type:"text",content:{text:"欢迎进入  聊天室"}}},];  
                let list = [];  
                //for(var pageLinShi =1;pageLinShi<3;pageLinShi++){  
                /* this.$http.get('cgr/listChatMsgByChatGroupId', {  
                    'userId': uni.getStorageSync('userId'), // 118,  432  
                    'chatGroupId': this.groupId, // 31 ,  62  
                    'page': 1, //pageLinShi  
                }).then((res) => { */  
                uni.request({  
                    url:'myrul',  
                     data: {  
                         'userId': uni.getStorageSync('userId'), // 118,  432  
                         'chatGroupId': this.groupId, // 31 ,  62  
                         'page': 1  
                        },  
                    success: (res) => {  
                    console.log(res);  
                    /* if(res.success == true && res.totalSize >0){  */  
                    res = res.data;  
                    if (res.success == true && res.data.length > 0) {  
                        var i = 0;  
                        /* for(;i<res.totalSize;i++){ */  
                        for (; i < res.data.length; i++) {  
                            /* let jiLu = {type:"user",msg:{id:res.data[i].id,type:"text",time:res.data[i].msgTime,userinfo:{uid:res.data[i].userId,username:res.data[i].userId,face:"/static/img/face.jpg"},content:res.data[i].msgMacro}} */ //  username:"大黑哥"   
                            let jiLu = {  
                                type: "user",  
                                msg: {  
                                    id: res.data[i].id,  
                                    type: "voice",  
                                    time: res.data[i].msgTime,  
                                    userinfo: {  
                                        uid: res.data[i].userId,  
                                        username: res.data[i].nickname,  
                                        face: "/static/img/face.jpg"  
                                    },  
                                    content: res.data[i].msgMacro  
                                }  
                            }  
                            //console.log(jiLu);  
                            list.unshift(jiLu);  
                            //this.msgList.unshift(jiLu);  
                        }  
                    }  
                },//).catch((e) => {  
                fail:(e)=>{  
                    console.log(e)  
                    console.log(JSON.stringify(e));  
                    setTimeout(function() {  
                        //_this.isRotate = false;  
                        uni.showToast({  
                            icon: 'none',  
                            position: 'bottom',  
                            title: '不行啊,请求超时,请稍后再试'  
                        });  
                    }, 3000);  

                }});  
                ///}  
                this.msgList = list;  
                this.scrollToBottom();  
                // 滚动到底部  
                this.$nextTick(function() {  
                    console.log('进入页面滚动到底部')  
                    //进入页面滚动到底部  
                    //this.scrollTop = 9999;  
                    this.scrollTop = 9999999;  
                    this.$nextTick(function() {  
                        this.scrollAnimation = true;  
                    });  
                });  
                //}   
                // 消息列表  
                //let list = [{type:"system",msg:{id:0,type:"text",content:{text:"欢迎进入HM-chat聊天室"}}},];  
                /* let list = [  
                    {type:"system",msg:{id:0,type:"text",content:{text:"欢迎进入HM-chat聊天室"}}},  
                    {type:"user",msg:{id:1,type:"text",time:"12:56",userinfo:{uid:0,username:"大黑哥",face:"/static/img/face.jpg"},content:{text:"为什么温度会相差那么大?"}}},  
                    {type:"user",msg:{id:2,type:"text",time:"12:57",userinfo:{uid:1,username:"售后客服008",face:"/static/img/im/face/face_2.jpg"},content:{text:"这个是有偏差的,两个温度相差十几二十度是很正常的,如果相差五十度,那即是质量问题了。"}}},  
                    {type:"user",msg:{id:3,type:"voice",time:"12:59",userinfo:{uid:1,username:"售后客服008",face:"/static/img/im/face/face_2.jpg"},content:{url:"/static/voice/1.mp3",length:"00:06"}}},  
                    {type:"user",msg:{id:4,type:"voice",time:"13:05",userinfo:{uid:0,username:"大黑哥",face:"/static/img/face.jpg"},content:{url:"/static/voice/2.mp3",length:"00:06"}}},  
                    {type:"user",msg:{id:5,type:"img",time:"13:05",userinfo:{uid:0,username:"大黑哥",face:"/static/img/face.jpg"},content:{url:"/static/img/p10.jpg",w:200,h:200}}},  
                    {type:"user",msg:{id:6,type:"img",time:"12:59",userinfo:{uid:1,username:"售后客服008",face:"/static/img/im/face/face_2.jpg"},content:{url:"/static/img/q.jpg",w:1920,h:1080}}},  
                    {type:"system",msg:{id:7,type:"text",content:{text:"欢迎进入HM-chat聊天室"}}},  

                    {type:"system",msg:{id:9,type:"redEnvelope",content:{text:"售后客服008领取了你的红包"}}},  
                    {type:"user",msg:{id:10,type:"redEnvelope",time:"12:56",userinfo:{uid:0,username:"大黑哥",face:"/static/img/face.jpg"},content:{blessing:"恭喜发财,大吉大利,万事如意",rid:0,isReceived:false}}},  
                    {type:"user",msg:{id:11,type:"redEnvelope",time:"12:56",userinfo:{uid:1,username:"售后客服008",face:"/static/img/im/face/face_2.jpg"},content:{blessing:"恭喜发财",rid:1,isReceived:false}}},  
                ] */  
                // 获取消息中的图片,并处理显示尺寸  
                /* for(let i=0;i<list.length;i++){  
                    if(list[i].type=='user'&&list[i].msg.type=="img"){  
                        list[i].msg.content = this.setPicSize(list[i].msg.content);  
                        this.msgImgList.push(list[i].msg.content.url);  
                    }  
                } */  

            },  

这段代码有什么问题吗?为何进入聊天页面的时候,滑动不到底部?而你的模板我运行了,可以滑动到底部

DCMarvel

DCMarvel

看了半天,你们俩讨论啥呢?怎么还扯到后台id了.滚动和id有什么关系???
光有js,html代码呢?

以下思路自己测试

页面滚动用

uni.pageScrollTo({  
    scrollTop: uni.getSystemInfoSync().screenHeight - 10,  
    duration: 300  
});

scroll-view组件滚动用 (大概代码,具体自己看https://uniapp.dcloud.io/component/scroll-view文档,自己验证)

 <scroll-view :scroll-into-view="'item_' + into">  
    <view v-for="(item,index) in 聊天列表" :key="index">  
     <view :id="'item_' + index">内容</view>  
    </view>  
 </scroll-view>  

有新的内容  
this.into = 聊天列表.length - 1 
  • jasonDev (作者)

    不知道放在哪,头疼。。。。。。。。scrollToId也用了,不起作用,有偿求教

    2021-05-30 10:10

  • DCMarvel

    回复 jasonDev: 你把源码发出来

    2021-05-30 10:32

  • jasonDev (作者)

    回复 DCMarvel: 源码很长的。加qq好吗?我的qq:1789270840

    2021-05-30 10:42

jasonDev

jasonDev (作者) - 努力

<template>  
    <view>  
        <view class="content" @touchstart="hideDrawer" :style="{height: style.contentViewHeight + 'px'}">  
            <scroll-view id="scrollview" class="msg-list" scroll-y="true" :scroll-with-animation="scrollAnimation"  
                :scroll-top="scrollTop" :scroll-into-view="scrollToView" @scrolltoupper="loadHistory"  
                upper-threshold="50" :style="{height: style.contentViewHeight + 'px'}">  
                <!-- 加载历史数据waitingUI -->  
                <view class="loading">  
                    <view class="spinner">  
                        <view class="rect1"></view>  
                        <view class="rect2"></view>  
                        <view class="rect3"></view>  
                        <view class="rect4"></view>  
                        <view class="rect5"></view>  
                    </view>  
                </view>  
                <view class="row" v-for="(row,index) in msgList" :key="index" :id="'msg'+row.msg.id">  
                    <!-- 系统消息 -->  
                    <block v-if="row.type=='system'">  
                        <view class="system">  
                            <!-- 文字消息 -->  
                            <view v-if="row.msg.type=='text'" class="text">  
                                {{row.msg.content.text}}  
                            </view>  
                            <!-- 领取红包消息 -->  
                            <view v-if="row.msg.type=='redEnvelope'" class="red-envelope">  
                                <image src="/static/img/red-envelope-chat.png"></image>  
                                {{row.msg.content.text}}  
                            </view>  
                        </view>  
                    </block>  
                    <!-- 用户消息 -->  
                    <block v-if="row.type=='user'">  
                        <!-- 自己发出的消息 -->  
                        <view class="my" v-if="row.msg.userinfo.uid==myuid">  
                            <!-- 左-消息 -->  
                            <view class="left">  
                                <!-- 文字消息 -->  
                                <view v-if="row.msg.type=='text'" class="bubble">  
                                    <!-- <rich-text :nodes="row.msg.content.text"></rich-text> -->  
                                    <rich-text :nodes="row.msg.content"></rich-text> <!-- 20210515 -->  
                                </view>  
                                <!-- 语言消息 -->  
                                <view v-if="row.msg.type=='voice'" class="bubble voice" @tap="playVoice(row.msg)"  
                                    :class="playMsgid == row.msg.id?'play':''">  
                                    <!-- <view class="length">{{row.msg.content.length}}</view> -->  
                                    <view class="icon my-voice"></view>  
                                </view>  
                            </view>  
                            <!-- 右-头像 -->  
                            <view class="right">  
                                <!-- <image :src="row.msg.userinfo.face"></image> -->  
                                <text>我</text>  
                            </view>  
                        </view>  
                        <!-- 别人发出的消息 -->  
                        <view class="other" v-if="row.msg.userinfo.uid!=myuid">  
                            <!-- 左-头像 -->  
                            <!-- <view class="left">  
                                <image :src="row.msg.userinfo.face"></image>  
                            </view> -->  
                            <!-- 右-用户名称-时间-消息 -->  
                            <view class="right">  
                                <view class="username">  
                                    <!-- <view class="name">{{row.msg.userinfo.uid}}</view> <view class="time">{{row.msg.time}}</view> -->  
                                    <view class="name">{{row.msg.userinfo.username}}</view>  
                                    <view class="time">{{row.msg.time}}</view>  
                                </view>  
                                <!-- 文字消息 -->  
                                <view v-if="row.msg.type=='text'" class="bubble">  
                                    <!-- <rich-text :nodes="row.msg.content.text"></rich-text> -->  
                                    <!-- 20210515 -->  
                                    <rich-text :nodes="row.msg.content"></rich-text>  
                                    <!-- <rich-text :nodes="row.msg.userinfo.uid"></rich-text>  
                                     <rich-text :nodes="myuid"></rich-text> -->  
                                </view>  
                                <!-- 语音消息 -->  
                                <view v-if="row.msg.type=='voice'" class="bubble voice" @tap="playVoice(row.msg)"  
                                    :class="playMsgid == row.msg.id?'play':''">  
                                    <view class="icon other-voice"></view>  
                                    <!-- <view class="length">{{row.msg.content.length}}</view> -->  
                                </view>  
                            </view>  
                        </view>  
                    </block>  
                </view>  
            </scroll-view>  
        </view>  
        <!-- 底部输入栏 -->  
        <view class="input-box" :class="popupLayerClass" @touchmove.stop.prevent="discard">  
            <!-- H5下不能录音,输入栏布局改动一下 -->  
            <!-- #ifndef H5 -->  
            <view class="voice">  
                <!-- <view class="icon" :class="isVoice?'jianpan':'yuyin'" @tap="switchVoice"></view> -->  
                <view class="icon" :class="'yuyin'"></view>  
            </view>  
            <!-- #endif -->  
            <!-- #ifdef H5 -->  
            <view class="more" @tap="showMore">  
                <view class="icon add"></view>  
            </view>  
            <!-- #endif -->  
            <view class="textbox">  
                <!-- <view class="voice-mode" :class="[isVoice?'':'hidden',recording?'recording':'']" @touchstart="voiceBegin"   
                @touchmove.stop.prevent="voiceIng" @touchend="voiceEnd" @touchcancel="voiceCancel">{{voiceTis}}</view> -->  
                <view class="voice-mode" :class="['','recording']" @touchstart="voiceBegin"  
                    @touchmove.stop.prevent="voiceIng" @touchend="voiceEnd" @touchcancel="voiceCancel">{{voiceTis}}  
                </view>  
                <!-- <view class="text-mode"  :class="isVoice?'hidden':''"> -->  
                <!-- <view class="text-mode"  :class="''">  
                    <view class="box">  
                        <textarea auto-height="true" v-model="textMsg" @focus="textareaFocus"/>  
                    </view>  
                    <view class="em" @tap="chooseEmoji">  
                        <view class="icon biaoqing"></view>  
                    </view>  
                </view> -->  
            </view>  
            <!-- #ifndef H5 -->  
            <!-- <view class="more" @tap="showMore">  
                <view class="icon add"></view>  
            </view> -->  
            <!-- #endif -->  
            <!-- <view class="send" :class="isVoice?'hidden':''" @tap="sendText">  
                <view class="btn">发送</view>  
            </view> -->  
        </view>  
        <!-- 录音UI效果 -->  
        <view class="record" :class="recording?'':'hidden'">  
            <view class="ing" :class="willStop?'hidden':''">  
                <view class="icon luyin2"></view>  
            </view>  
            <view class="cancel" :class="willStop?'':'hidden'">  
                <view class="icon chehui"></view>  
            </view>  
            <view class="tis" :class="willStop?'change':''">{{recordTis}}</view>  
        </view>  
    </view>  
</template>  
<script>  
    export default {  
        data() {  
            return {  
                // 聊天页面时时滚动样式  
                style: {  
                    pageHeight: 0,  
                    contentViewHeight: 0,  
                    footViewHeight: 90,  
                    mitemHeight: 0  
                },  
                secondTouch: true,  
                // 确保websocket是打开状态  
                is_open_socket: false,  
                timer: '',  
                groupId: -1,  
                page: 1,  
                //文字消息  
                textMsg: '',  
                //消息列表  
                isHistoryLoading: false,  
                scrollAnimation: false,  
                scrollTop: 0,  
                scrollToView: '',  
                msgList: [],  
                msgImgList: [],  
                //myuid:0,  
                myuid: uni.getStorageSync("userId"),  
                //录音相关参数  
                // #ifndef H5  
                //H5不能录音  
                RECORDER: uni.getRecorderManager(),  
                // #endif  
                isVoice: false,  
                voiceTis: '按住 说话',  
                recordTis: "手指上滑 取消发送",  
                recording: false,  
                willStop: false,  
                initPoint: {  
                    identifier: 0,  
                    Y: 0  
                },  
                recordTimer: null,  
                recordLength: 0,  

                //播放语音相关参数  
                AUDIO: uni.createInnerAudioContext(),  
                playMsgid: null,  
                VoiceTimer: null,  
                // 抽屉参数  
                popupLayerClass: '',  
                // more参数  
                hideMore: true,  
                //表情定义  
                hideEmoji: true,  

                //红包相关参数  
                windowsState: '',  
                redenvelopeData: {  
                    rid: null, //红包ID  
                    from: null,  
                    face: null,  
                    blessing: null,  
                    money: null,  
                }  
            };  
        },  
        onReady() {  
            this.$nextTick(function() {  
                console.log('进入页面滚动到底部')  
                //进入页面滚动到底部  
                //this.scrollTop = 9999;  
                this.scrollTop = 9999999;  
                this.$nextTick(function() {  
                    this.scrollAnimation = true;  
                });  
            });  
        },  
        created() {  
            const res = uni.getSystemInfoSync(); //获取手机可使用窗口高度     api为获取系统信息同步接口  
            this.style.pageHeight = res.windowHeight;  
            this.style.contentViewHeight = res.windowHeight - uni.getSystemInfoSync().screenWidth / 750 * (100) -  
            70; //像素   因为给出的是像素高度 然后我们用的是upx  所以换算一下   
            this.scrollToBottom(); //创建后调用回到底部方法  
        },  
        onLoad(option) {  
            uni.setNavigationBarTitle({ // 这里加载标题  
                title: option.groupName + '分组'  
            });  
            this.groupId = option.groupId;  
            // 进入这个页面的时候创建websocket连接【整个页面随时使用】  
            this.connectSocketInit();  
            this.timer = setInterval(this.xinTiao, 30000);  
            this.getMsgList();  
            //语音自然播放结束  
            this.AUDIO.onEnded((res) => {  
                this.playMsgid = null;  
            });  
            // #ifndef H5  
            //录音开始事件  
            this.RECORDER.onStart((e) => {  
                this.recordBegin(e);  
            })  
            //录音结束事件  
            this.RECORDER.onStop((e) => {  
                this.recordEnd(e);  
            })  
            // #endif  
        },  
        onShow() {  
            this.scrollTop = 9999999;  

            //模板借由本地缓存实现发红包效果,实际应用中请不要使用此方法。  
            //  

        },  
        beforeDestroy() {  
            //this.closeSocket();  
        },  
        methods: {  

            /**  
             * @author gongliying  
             * @date 2019-07-26       https://www.cnblogs.com/gongliying/p/11258189.html  
             * @information 跳转页面底部  
             */  
            scrollToBottom: function() {  
                console.log('in scrollToBottom')  
                let that = this;  
                let query = uni.createSelectorQuery();  
                console.log('in scrollToBottom   2')  
                query.selectAll('.row').boundingClientRect();  
                query.select('#scrollview').boundingClientRect();  
                console.log('in scrollToBottom  3')  
                query.exec((res) => {  
                    console.log("得到布局位置信息:" + JSON.stringify(res));  
                    console.log("节点离页面顶部的距离为:" + res[0].top);  
                    that.style.mitemHeight = 0;  
                    res[0].forEach((rect) => {  
                        console.log('rect.height= ' + rect.height);  
                        that.style.mitemHeight = that.style.mitemHeight + rect.height + 40;  
                    })  
                    //获取所有内部子元素的高度  
                    // 因为vue的虚拟DOM 每次生成的新消息都是之前的,所以采用异步setTimeout    主要就是添加了这红字                          
                    setTimeout(() => {  
                        if (that.style.mitemHeight > (that.style.contentViewHeight -  
                            100)) { //判断子元素高度是否大于显示高度  
                            that.scrollTop = that.style.mitemHeight - that.style  
                                .contentViewHeight //用子元素的高度减去显示的高度就获益获得序言滚动的高度  
                        }  
                    }, 100);  

                })  
            },  
            xinTiao: function() {  
                //setInterval(this.run,5000);                 
                let _this = this;  
                let tempData = '{"type":"1","userid": "' + uni.getStorageSync("userId") + '"}';  
                console.log(tempData)  
                _this.socketTask.send({  
                    data: tempData, /// '{"type":"1","userid": '+uni.getStorageSync("userId")+'}',  
                    async success() {  
                        //console.log("消息发送成功");  
                    },  
                });  
            },  
            // 进入这个页面的时候创建websocket连接【整个页面随时使用】  
            connectSocketInit() {  
                // 创建一个this.socketTask对象【发送、接收、关闭socket都由这个对象操作】  
                this.socketTask = uni.connectSocket({  
                    // 【非常重要】必须确保你的服务器是成功的,如果是手机测试千万别使用ws://127.0.0.1:9099【特别容易犯的错误】  
                    url: 'ws://www.bjcn-tech.com:30190/vom/api/websocket/61', // 31',//'后台的地址', **例如:ws: '192.168.10.101:8080'**  
                    success(data) {  
                        console.log("websocket连接成功");  
                    },  
                });  

                // 消息的发送和接收必须在正常连接打开中,才能发送或接收【否则会失败】  
                this.socketTask.onOpen((res) => {  
                    console.log("WebSocket连接正常打开中...!");  
                    this.is_open_socket = true;  
                    this.xinTiao();  
                    // 注:只有连接正常打开中 ,才能正常成功发送消息  

                    /* this.socketTask.send({  
                        data:  '{"type":"2","userid":"118","groupid":"31","mp3":"uni-app发送一条消息222"}',  
                        async success() {  
                            console.log("消息发送成功");  
                        },  
                    }); */  
                    // 注:只有连接正常打开中 ,才能正常收到消息  
                    this.socketTask.onMessage((res) => {  
                        console.log("收到服务器内容:" + res.data);  
                        if (JSON.parse(res.data).type == "2") {  
                            console.log("收到服务器内容:" + res.data);  
                            console.log("收到服务器内容:" + typeof(JSON.parse(res.data).type));  
                            console.log("收到服务器内容:" + JSON.parse(res.data).userid + '****' + JSON.parse(res  
                                .data).username);  
                            console.log('in this.socketTask.onMessage((res)')  
                            var nowDate = new Date();  
                            let lastid = this.msgList[this.msgList.length - 1].msg.id;  
                            lastid++;  
                            if (JSON.parse(res.data).userid != uni.getStorageSync('userId')) {  
                                /* let msg = {type:'user',msg:{id:lastid,time:nowDate.getHours()+":"+nowDate.getMinutes(),type:'text',userinfo:{uid:JSON.parse(res.data).userid,username:"大黑哥",face:"/static/img/face.jpg"},content:res.data}} */  
                                let msg = {  
                                    type: 'user',  
                                    msg: {  
                                        id: lastid,  
                                        time: nowDate.getHours() + ":" + nowDate.getMinutes(),  
                                        type: 'voice',  
                                        userinfo: {  
                                            uid: JSON.parse(res.data).userid,  
                                            username: JSON.parse(res.data).username,  
                                            face: "/static/img/face.jpg"  
                                        },  
                                        content: JSON.parse(res.data).mp3  
                                    }  
                                } //username:"大黑哥"        content:res.data  
                                // uid 得改  username:"大黑哥"  
                                // 发送消息  
                                this.screenMsg(msg);  
                            }  
                        }  
                    });  
                })  
                // 这里仅是事件监听【如果socket关闭了会执行】  
                this.socketTask.onClose(() => {  
                    this.is_open_socket = false;  
                    console.log("已经被关闭了")  
                })  
            },  
            // 关闭websocket【离开这个页面的时候执行关闭】  
            /* closeSocket() {  
                this.socketTask.close({  
                    success(res) {  
                        this.is_open_socket = false;  
                        console.log("关闭成功", res)  
                    },  
                    fail(err) {  
                        console.log("关闭失败", err)  
                    }  
                })  
            }, */  
            // 离开也不关闭   20210516  
            // 接受消息(筛选处理)  
            screenMsg(msg) {  
                //从长连接处转发给这个方法,进行筛选处理  
                if (msg.type == 'system') {  
                    // 系统消息  
                    switch (msg.msg.type) {  
                        case 'text':  
                            this.addSystemTextMsg(msg);  
                            break;  
                        case 'redEnvelope':  
                            this.addSystemRedEnvelopeMsg(msg);  
                            break;  
                    }  
                } else if (msg.type == 'user') {  
                    // 用户消息  
                    switch (msg.msg.type) {  
                        case 'text':  
                            this.addTextMsg(msg);  
                            break;  
                        case 'voice':  
                            this.addVoiceMsg(msg);  
                            //this.addVoiceMsg(msg.msg.mp3);  
                            break;  
                        case 'img':  
                            this.addImgMsg(msg);  
                            break;  
                        case 'redEnvelope':  
                            this.addRedEnvelopeMsg(msg);  
                            break;  
                    }  
                    console.log('用户消息');  
                    //非自己的消息震动  
                    if (msg.msg.userinfo.uid != this.myuid) {  
                        console.log('振动');  
                        uni.vibrateLong();  
                        this.playVoice(msg.msg);  
                        /* const innerAudioContext = uni.createInnerAudioContext();  
                        innerAudioContext.autoplay = true;  
                        innerAudioContext.src = '/static/audio/6000.mp3';  
                        innerAudioContext.onPlay(() => {  
                          console.log('开始播放');  
                        });  
                        innerAudioContext.onError((res) => {  
                          console.log(res.errMsg);  
                          console.log(res.errCode);  
                        });  */  
                    }  
                }  
                this.$nextTick(function() {  
                    // 滚动到底  
                    this.scrollToView = 'msg' + msg.msg.id  
                    console.log('this.scrollToView= in screenMsg' + this.scrollToView)  
                });  
            },  

            //触发滑动到顶部(加载历史信息记录)  
            loadHistory(e) {  
                //let that = this;                
                console.log('in loadHistory')  
                if (this.isHistoryLoading) {  
                    return;  
                }  
                console.log('in loadHistory  2');  
                console.log(typeof(this.page))  
                this.page = this.page + 1;  
                console.log('前面的  ' + this.page);  
                this.isHistoryLoading = true; //参数作为进入请求标识,防止重复请求  
                this.scrollAnimation = false; //关闭滑动动画  
                let Viewid = this.msgList[0].msg.id; //记住第一个信息ID  
                //本地模拟请求历史记录效果  
                setTimeout(() => {  
                    // 消息列表  
                    /* let list = [  
                        {type:"user",msg:{id:1,type:"text",time:"12:56",userinfo:{uid:0,username:"大黑哥",face:"/static/img/face.jpg"},content:{text:"为什么温度会相差那么大?"}}},  
                        {type:"user",msg:{id:2,type:"text",time:"12:57",userinfo:{uid:1,username:"售后客服008",face:"/static/img/im/face/face_2.jpg"},content:{text:"这个是有偏差的,两个温度相差十几二十度是很正常的,如果相差五十度,那即是质量问题了。"}}},  
                        {type:"user",msg:{id:3,type:"voice",time:"12:59",userinfo:{uid:1,username:"售后客服008",face:"/static/img/im/face/face_2.jpg"},content:{url:"/static/voice/1.mp3",length:"00:06"}}},  
                        {type:"user",msg:{id:4,type:"voice",time:"13:05",userinfo:{uid:0,username:"大黑哥",face:"/static/img/face.jpg"},content:{url:"/static/voice/2.mp3",length:"00:06"}}},  
                    ] */  
                    console.log(uni.getStorageSync('userId'));  
                    console.log(this.groupId);  
                    console.log(this.page);  
                    uni.request({  
                        url:'myUrl',  
                         data: {  
                             'userId': uni.getStorageSync('userId'), // 118,  432  
                             'chatGroupId': this.groupId, // 31 ,  62  
                             'page':this.page  
                            },  
                    /* this.$http.get('cgr/listChatMsgByChatGroupId', {  
                        'userId': uni.getStorageSync('userId'), // 118,  432  
                        'chatGroupId': this.groupId, // 31 ,  62  
                        'page': this.page  
                    }).then((res) => { */  
                    success: (res) => {  
                        var list = [];  
                        console.log(res);  
                        res = res.data;  
                        /* if(res.success == true && res.totalSize >0){ */  
                        if (res.success == true && res.data.length > 0) {  
                            var i = 0;  
                            /* for(;i<res.totalSize;i++){ */  
                            for (; i < res.data.length; i++) {  
                                /* let jiLu = {type:"user",msg:{id:res.data[i].id,type:"voice",time:res.data[i].msgTime,userinfo:{uid:res.data[i].userId,username:res.data[i].userId,face:"/static/img/face.jpg"},content:{text:res.data[i].msgMacro}}} */ //username:"大黑哥"  
                                let jiLu = {  
                                    type: "user",  
                                    msg: {  
                                        id: res.data[i].id,  
                                        type: "voice",  
                                        time: res.data[i].msgTime,  
                                        userinfo: {  
                                            uid: res.data[i].userId,  
                                            username: res.data[i].nickname,  
                                            face: "/static/img/face.jpg"  
                                        },  
                                        content: res.data[i].msgMacro  
                                    }  
                                }  
                                console.log(jiLu);  
                                list.push(jiLu);  
                            }  
                        } else {  
                            this.scrollTop = 0;  
                            setTimeout(function() {  
                                //_this.isRotate = false;  
                                uni.showToast({  
                                    icon: 'none',  
                                    position: 'bottom',  
                                    title: '已经到底最顶端,上面没有了'  
                                });  
                            }, 3000);  
                            this.$nextTick(function() {  
                                this.scrollAnimation = false;  
                            });  
                        }  
                        //this.msgList = list;  
                        // 获取消息中的图片,并处理显示尺寸  
                        for (let i = 0; i < list.length; i++) {  
                            /* if(list[i].type=='user'&&list[i].msg.type=="img"){  
                                list[i].msg.content = this.setPicSize(list[i].msg.content);  
                                this.msgImgList.unshift(list[i].msg.content.url);  
                            }  
                            list[i].msg.id = Math.floor(Math.random()*1000+1); */  
                            this.msgList.unshift(list[i]);  
                        }  
                    },//).catch((e) => {  
                    fail:(e)=>{  
                        console.log(e);  
                        console.log(JSON.stringify(e));  
                        setTimeout(function() {  
                            //_this.isRotate = false;  
                            uni.showToast({  
                                icon: 'none',  
                                position: 'bottom',  
                                title: '不行啊,请求超时,请稍后再试'  
                            });  
                        }, 3000);  
                    }});  

                    //这段代码很重要,不然每次加载历史数据都会跳到顶部  
                    this.$nextTick(function() {  
                        this.scrollToView = 'msg' + Viewid; //跳转上次的第一行信息位置  
                        this.$nextTick(function() {  
                            this.scrollAnimation = true; //恢复滚动动画  
                        });  
                        console.log('this.scrollToView in loadHistory  ' + this.scrollToView)  
                    });  
                    this.isHistoryLoading = false;  

                }, 1000);  
            },  
            // 加载初始页面消息  
            getMsgList() {  
                //let list = [{type:"system",msg:{id:0,type:"text",content:{text:"欢迎进入  聊天室"}}},];  
                let list = [];  
                //for(var pageLinShi =1;pageLinShi<3;pageLinShi++){  
                /* this.$http.get('cgr/listChatMsgByChatGroupId', {  
                    'userId': uni.getStorageSync('userId'), // 118,  432  
                    'chatGroupId': this.groupId, // 31 ,  62  
                    'page': 1, //pageLinShi  
                }).then((res) => { */  
                uni.request({  
                    url:'myUrl',  
                     data: {  
                         'userId': uni.getStorageSync('userId'), // 118,  432  
                         'chatGroupId': this.groupId, // 31 ,  62  
                         'page': 1  
                        },  
                    success: (res) => {  
                    console.log(res);  
                    /* if(res.success == true && res.totalSize >0){  */  
                    res = res.data;  
                    if (res.success == true && res.data.length > 0) {  
                        var i = 0;  
                        /* for(;i<res.totalSize;i++){ */  
                        for (; i < res.data.length; i++) {  
                            /* let jiLu = {type:"user",msg:{id:res.data[i].id,type:"text",time:res.data[i].msgTime,userinfo:{uid:res.data[i].userId,username:res.data[i].userId,face:"/static/img/face.jpg"},content:res.data[i].msgMacro}} */ //  username:"大黑哥"   
                            let jiLu = {  
                                type: "user",  
                                msg: {  
                                    id: res.data[i].id,  
                                    type: "voice",  
                                    time: res.data[i].msgTime,  
                                    userinfo: {  
                                        uid: res.data[i].userId,  
                                        username: res.data[i].nickname,  
                                        face: "/static/img/face.jpg"  
                                    },  
                                    content: res.data[i].msgMacro  
                                }  
                            }  
                            //console.log(jiLu);  
                            list.unshift(jiLu);  
                            //this.msgList.unshift(jiLu);  
                        }  
                    }  
                },//).catch((e) => {  
                fail:(e)=>{  
                    console.log(e)  
                    console.log(JSON.stringify(e));  
                    setTimeout(function() {  
                        //_this.isRotate = false;  
                        uni.showToast({  
                            icon: 'none',  
                            position: 'bottom',  
                            title: '不行啊,请求超时,请稍后再试'  
                        });  
                    }, 3000);  

                }});  
                ///}  
                this.msgList = list;  
                this.scrollToBottom();  
                // 滚动到底部  
                this.$nextTick(function() {  
                    console.log('进入页面滚动到底部')  
                    //进入页面滚动到底部  
                    //this.scrollTop = 9999;  
                    this.scrollTop = 9999999;  
                    this.$nextTick(function() {  
                        this.scrollAnimation = true;  
                    });  
                });  
                //}   
                // 消息列表  
                //let list = [{type:"system",msg:{id:0,type:"text",content:{text:"欢迎进入HM-chat聊天室"}}},];  
                /* let list = [  
                    {type:"system",msg:{id:0,type:"text",content:{text:"欢迎进入HM-chat聊天室"}}},  
                    {type:"user",msg:{id:1,type:"text",time:"12:56",userinfo:{uid:0,username:"大黑哥",face:"/static/img/face.jpg"},content:{text:"为什么温度会相差那么大?"}}},  
                    {type:"user",msg:{id:2,type:"text",time:"12:57",userinfo:{uid:1,username:"售后客服008",face:"/static/img/im/face/face_2.jpg"},content:{text:"这个是有偏差的,两个温度相差十几二十度是很正常的,如果相差五十度,那即是质量问题了。"}}},  
                    {type:"user",msg:{id:3,type:"voice",time:"12:59",userinfo:{uid:1,username:"售后客服008",face:"/static/img/im/face/face_2.jpg"},content:{url:"/static/voice/1.mp3",length:"00:06"}}},  
                    {type:"user",msg:{id:4,type:"voice",time:"13:05",userinfo:{uid:0,username:"大黑哥",face:"/static/img/face.jpg"},content:{url:"/static/voice/2.mp3",length:"00:06"}}},  
                    {type:"user",msg:{id:5,type:"img",time:"13:05",userinfo:{uid:0,username:"大黑哥",face:"/static/img/face.jpg"},content:{url:"/static/img/p10.jpg",w:200,h:200}}},  
                    {type:"user",msg:{id:6,type:"img",time:"12:59",userinfo:{uid:1,username:"售后客服008",face:"/static/img/im/face/face_2.jpg"},content:{url:"/static/img/q.jpg",w:1920,h:1080}}},  
                    {type:"system",msg:{id:7,type:"text",content:{text:"欢迎进入HM-chat聊天室"}}},  

                    {type:"system",msg:{id:9,type:"redEnvelope",content:{text:"售后客服008领取了你的红包"}}},  
                    {type:"user",msg:{id:10,type:"redEnvelope",time:"12:56",userinfo:{uid:0,username:"大黑哥",face:"/static/img/face.jpg"},content:{blessing:"恭喜发财,大吉大利,万事如意",rid:0,isReceived:false}}},  
                    {type:"user",msg:{id:11,type:"redEnvelope",time:"12:56",userinfo:{uid:1,username:"售后客服008",face:"/static/img/im/face/face_2.jpg"},content:{blessing:"恭喜发财",rid:1,isReceived:false}}},  
                ] */  
                // 获取消息中的图片,并处理显示尺寸  
                /* for(let i=0;i<list.length;i++){  
                    if(list[i].type=='user'&&list[i].msg.type=="img"){  
                        list[i].msg.content = this.setPicSize(list[i].msg.content);  
                        this.msgImgList.push(list[i].msg.content.url);  
                    }  
                } */  

            },  

            //更多功能(点击+弹出)   
            showMore() {  
                this.isVoice = false;  
                this.hideEmoji = true;  
                if (this.hideMore) {  
                    this.hideMore = false;  
                    this.openDrawer();  
                } else {  
                    this.hideDrawer();  
                }  
            },  
            // 打开抽屉  
            openDrawer() {  
                this.popupLayerClass = 'showLayer';  
            },  
            // 隐藏抽屉  
            hideDrawer() {  
                this.popupLayerClass = '';  
                setTimeout(() => {  
                    this.hideMore = true;  
                    this.hideEmoji = true;  
                }, 150);  
            },  

            //获取焦点,如果不是选表情ing,则关闭抽屉  
            textareaFocus() {  
                if (this.popupLayerClass == 'showLayer' && this.hideMore == false) {  
                    this.hideDrawer();  
                }  
            },  
            // 发送文字消息  
            sendText() {  
                this.hideDrawer(); //隐藏抽屉  
                if (!this.textMsg) {  
                    return;  
                }  
                //let content = this.replaceEmoji(this.textMsg);  
                /* let content =this.textMsg;  
                let msg = {text:content}  
                this.sendMsg(msg,'text'); */  
                console.log('in sendText' + this.textMsg);  
                this.sendMsg(this.textMsg, 'text'); //只发文字  
                this.textMsg = ''; //清空输入框  
            },  

            // 发送消息  
            sendMsg(content, type) {  
                if (this.is_open_socket) {  
                    //var json = '{"type":"2","userid":"118","groupid":"31","mp3":"'+content+'"}';  
                    var json = '{"type":"2","userid":"' + 434 + '","username":"' + uni  
                        .getStorageSync("username") + '","groupid":"' + this.groupId + '","mp3":"' + content + '"}';  
                    console.log(json);  
                    // websocket的服务器的原理是:发送一次消息,同时返回一组数据【否则服务器会进去死循环崩溃】  
                    this.socketTask.send({  
                        data: json, //data要字符串!!!!  
                        //data:"关闭吗",  
                        async success() {  
                            console.log("消息发送成功");  
                        },  
                    });  
                    //message.isSend = true;  
                    //this.msgListMy.push(JSON.parse(json));  
                    //this.scrollBottom();  
                    //this.msg = ""  
                }  

                //实际应用中,此处应该提交长连接,模板仅做本地处理。  
                var nowDate = new Date();  
                let lastid = this.msgList[this.msgList.length - 1].msg.id;  
                lastid++;  
                let msg = {  
                    type: 'user',  
                    msg: {  
                        id: lastid,  
                        time: nowDate.getHours() + ":" + nowDate.getMinutes(),  
                        type: type,  
                        userinfo: {  
                            uid: 434,  
                            username: "大黑哥",  
                            face: "/static/img/face.jpg"  
                        },  
                        content: content  
                    }  
                }  
                // 发送消息  
                this.screenMsg(msg);  
                // 定时器模拟对方回复,三秒  
                /* setTimeout(()=>{  
                    lastid = this.msgList[this.msgList.length-1].msg.id;  
                    lastid++;  
                    msg = {type:'user',msg:{id:lastid,time:nowDate.getHours()+":"+nowDate.getMinutes(),type:type,userinfo:{uid:1,username:"售后客服008",face:"/static/img/im/face/face_2.jpg"},content:content}}  
                    // 本地模拟发送消息  
                    this.screenMsg(msg);  
                },3000) */  
            },  

            // 添加文字消息到列表  
            addTextMsg(msg) {  
                console.log('in addTextMsg,and msg = ' + msg)  
                this.msgList.push(msg);  
                this.$set(this.msgList, this.msgList.length - 1, this.msgList[this.msgList.length - 1]);  

                //debugger;  
                console.log(this.msgList[this.msgList.length - 1].msg.content)  
            },  
            // 添加语音消息到列表  
            addVoiceMsg(msg) {  
                this.msgList.push(msg);  
                this.$set(this.msgList, this.msgList.length - 1, this.msgList[this.msgList.length - 1]);  
                this.scrollToBottom();  

                //this.playVoice(msg.msg);  

            },  
            sendSystemMsg(content, type) {  
                let lastid = this.msgList[this.msgList.length - 1].msg.id;  
                lastid++;  
                let row = {  
                    type: "system",  
                    msg: {  
                        id: lastid,  
                        type: type,  
                        content: content  
                    }  
                };  
                this.screenMsg(row)  
            },  
            // 播放语音  
            playVoice(msg) {  
                console.log('in playVoice(msg)')  
                console.log('msg.id= ' + msg.id)  
                console.log('msg.content.url=' + msg.content)  
                console.log(msg)  

                this.playMsgid = msg.id;  
                //this.AUDIO.src = msg.content.url;  
                this.AUDIO.src = 'http://www.bjcn-tech.com:30180/uploadFiles/socketMp3/' + msg.content;  
                //if(this.secondTouch){  
                this.$nextTick(function() {  
                    this.AUDIO.play();  
                    this.secondTouch = false;  
                });  
                /* }else{  
                    this.AUDIO.stop();  
                    this.secondTouch= true;  
                } */  
            },  
            // 录音开始  
            voiceBegin(e) {  
                if (e.touches.length > 1) {  
                    return;  
                }  
                this.initPoint.Y = e.touches[0].clientY;  
                this.initPoint.identifier = e.touches[0].identifier;  
                this.RECORDER.start({  
                    format: "mp3"  
                }); //录音开始,  
            },  
            //录音开始UI效果  
            recordBegin(e) {  
                this.recording = true;  
                this.voiceTis = '松开 结束';  
                this.recordLength = 0;  
                this.recordTimer = setInterval(() => {  
                    this.recordLength++;  
                }, 1000)  
            },  
            // 录音被打断  
            voiceCancel() {  
                this.recording = false;  
                this.voiceTis = '按住 说话';  
                this.recordTis = '手指上滑 取消发送'  
                this.willStop = true; //不发送录音  
                this.RECORDER.stop(); //录音结束  
            },  
            // 录音中(判断是否触发上滑取消发送)  
            voiceIng(e) {  
                if (!this.recording) {  
                    return;  
                }  
                let touche = e.touches[0];  
                //上滑一个导航栏的高度触发上滑取消发送  
                if (this.initPoint.Y - touche.clientY >= uni.upx2px(100)) {  
                    this.willStop = true;  
                    this.recordTis = '松开手指 取消发送'  
                } else {  
                    this.willStop = false;  
                    this.recordTis = '手指上滑 取消发送'  
                }  
            },  
            // 结束录音  
            voiceEnd(e) {  
                if (!this.recording) {  
                    return;  
                }  
                this.recording = false;  
                this.voiceTis = '按住 说话';  
                this.recordTis = '手指上滑 取消发送'  
                this.RECORDER.stop(); //录音结束  
            },  
            //录音结束(回调文件)  
            recordEnd(e) {  
                clearInterval(this.recordTimer);  
                if (!this.willStop) {  
                    console.log("e: " + JSON.stringify(e));  
                    //console.log(this.uploadMp3Action(e));  
                    //var myFirstPromise =  this.uploadMp3Action(e);      
                    uni.showLoading({  
                        title: '录音上传中...'  
                    });  
                    const uploadTask = uni.uploadFile({  
                        url: 'myUrl',  
                        filePath: e.tempFilePath, //filePath,//录音结束后返回的临时路径  
                        //name: 'audio',  
                        name: 'file',  
                        success: (uploadFileRes) => {  
                            console.log(JSON.stringify(uploadFileRes.data));  
                            console.log(JSON.parse(uploadFileRes.data));  
                            console.log(JSON.parse(uploadFileRes.data).success)  
                            console.log(JSON.parse(uploadFileRes.data).data[0].appPath);  
                            if (JSON.stringify(uploadFileRes.data) != "" && JSON.parse(uploadFileRes.data)  
                                .success) {  
                                /* let msg = {  
                                    length:0,  
                                    url:JSON.parse(uploadFileRes.data).data[0].appPath,//e.tempFilePath  
                                }  
                                let min = parseInt(this.recordLength/60);  
                                let sec = this.recordLength%60;  
                                min = min<10?'0'+min:min;  
                                sec = sec<10?'0'+sec:sec;  
                                msg.length = min+':'+sec;   
                                this.sendMsg(msg,'voice');*/  
                                this.sendMsg(JSON.parse(uploadFileRes.data).data[0].appPath, 'voice');  
                            }  
                        },  
                        fail: (res) => {  
                            console.log(JSON.stringify(res));  
                        }  
                    });  
                    uni.hideLoading();  

                } else {  
                    console.log('取消发送录音');  
                }  
                this.willStop = false;  
            },  
            // 切换语音/文字输入  
            switchVoice() {  
                this.hideDrawer();  
                this.isVoice = this.isVoice ? false : true;  
            },  
            discard() {  
                return;  
            }  
        }  
    }  
</script>  
<style lang="scss">  
    @import "./HM-chat/css/style.scss";  
</style>  
DCMarvel

DCMarvel

修改部分加粗了 ,复制时注意删除加粗的MD语法.代码自行验证.

<template>  
    <view>  
        <view class="content" @touchstart="hideDrawer" :style="{height: style.contentViewHeight + 'px'}">  
            <scroll-view id="scrollview" class="msg-list" scroll-y="true" :scroll-with-animation="scrollAnimation"  
                :scroll-top="scrollTop" :scroll-into-view="scrollToView" @scrolltoupper="loadHistory"  
                upper-threshold="50" :style="{height: style.contentViewHeight + 'px'}">  

###<!-- 这里是顶部 -->  
###<view class="" id="top"></view>  

                <!-- 加载历史数据waitingUI -->  
                <view class="loading">  
                    <view class="spinner">  
                        <view class="rect1"></view>  
                        <view class="rect2"></view>  
                        <view class="rect3"></view>  
                        <view class="rect4"></view>  
                        <view class="rect5"></view>  
                    </view>  
                </view>  

###<!-- 这里使用了index 不依赖后端数据 -->  
###<view class="row" v-for="(row,index) in msgList" :key="index" :id="'msg'+index">  

                    <!-- 系统消息 -->  
                    <block v-if="row.type=='system'">  
                        <view class="system">  
                            <!-- 文字消息 -->  
                            <view v-if="row.msg.type=='text'" class="text">  
                                {{row.msg.content.text}}  
                            </view>  
                            <!-- 领取红包消息 -->  
                            <view v-if="row.msg.type=='redEnvelope'" class="red-envelope">  
                                <image src="/static/img/red-envelope-chat.png"></image>  
                                {{row.msg.content.text}}  
                            </view>  
                        </view>  
                    </block>  
                    <!-- 用户消息 -->  
                    <block v-if="row.type=='user'">  
                        <!-- 自己发出的消息 -->  
                        <view class="my" v-if="row.msg.userinfo.uid==myuid">  
                            <!-- 左-消息 -->  
                            <view class="left">  
                                <!-- 文字消息 -->  
                                <view v-if="row.msg.type=='text'" class="bubble">  
                                    <!-- <rich-text :nodes="row.msg.content.text"></rich-text> -->  
                                    <rich-text :nodes="row.msg.content"></rich-text> <!-- 20210515 -->  
                                </view>  
                                <!-- 语言消息 -->  
                                <view v-if="row.msg.type=='voice'" class="bubble voice" @tap="playVoice(row.msg)"  
                                    :class="playMsgid == row.msg.id?'play':''">  
                                    <!-- <view class="length">{{row.msg.content.length}}</view> -->  
                                    <view class="icon my-voice"></view>  
                                </view>  
                            </view>  
                            <!-- 右-头像 -->  
                            <view class="right">  
                                <!-- <image :src="row.msg.userinfo.face"></image> -->  
                                <text>我</text>  
                            </view>  
                        </view>  
                        <!-- 别人发出的消息 -->  
                        <view class="other" v-if="row.msg.userinfo.uid!=myuid">  
                            <!-- 左-头像 -->  
                            <!-- <view class="left">    
                                <image :src="row.msg.userinfo.face"></image>    
                            </view> -->  
                            <!-- 右-用户名称-时间-消息 -->  
                            <view class="right">  
                                <view class="username">  
                                    <!-- <view class="name">{{row.msg.userinfo.uid}}</view> <view class="time">{{row.msg.time}}</view> -->  
                                    <view class="name">{{row.msg.userinfo.username}}</view>  
                                    <view class="time">{{row.msg.time}}</view>  
                                </view>  
                                <!-- 文字消息 -->  
                                <view v-if="row.msg.type=='text'" class="bubble">  
                                    <!-- <rich-text :nodes="row.msg.content.text"></rich-text> -->  
                                    <!-- 20210515 -->  
                                    <rich-text :nodes="row.msg.content"></rich-text>  
                                    <!-- <rich-text :nodes="row.msg.userinfo.uid"></rich-text>    
                                     <rich-text :nodes="myuid"></rich-text> -->  
                                </view>  
                                <!-- 语音消息 -->  
                                <view v-if="row.msg.type=='voice'" class="bubble voice" @tap="playVoice(row.msg)"  
                                    :class="playMsgid == row.msg.id?'play':''">  
                                    <view class="icon other-voice"></view>  
                                    <!-- <view class="length">{{row.msg.content.length}}</view> -->  
                                </view>  
                            </view>  
                        </view>  
                    </block>  
                </view>  

###<!-- 这里是底部 -->  
###<view class="" id="bottom"></view>  

            </scroll-view>  
        </view>  
        <!-- 底部输入栏 -->  
        <view class="input-box" :class="popupLayerClass" @touchmove.stop.prevent="discard">  
            <!-- H5下不能录音,输入栏布局改动一下 -->  
            <!-- #ifndef H5 -->  
            <view class="voice">  
                <!-- <view class="icon" :class="isVoice?'jianpan':'yuyin'" @tap="switchVoice"></view> -->  
                <view class="icon" :class="'yuyin'"></view>  
            </view>  
            <!-- #endif -->  
            <!-- #ifdef H5 -->  
            <view class="more" @tap="showMore">  
                <view class="icon add"></view>  
            </view>  
            <!-- #endif -->  
            <view class="textbox">  
                <!-- <view class="voice-mode" :class="[isVoice?'':'hidden',recording?'recording':'']" @touchstart="voiceBegin"     
                @touchmove.stop.prevent="voiceIng" @touchend="voiceEnd" @touchcancel="voiceCancel">{{voiceTis}}</view> -->  
                <view class="voice-mode" :class="['','recording']" @touchstart="voiceBegin"  
                    @touchmove.stop.prevent="voiceIng" @touchend="voiceEnd" @touchcancel="voiceCancel">{{voiceTis}}  
                </view>  
                <!-- <view class="text-mode"  :class="isVoice?'hidden':''"> -->  
                <!-- <view class="text-mode"  :class="''">    
                    <view class="box">    
                        <textarea auto-height="true" v-model="textMsg" @focus="textareaFocus"/>    
                    </view>    
                    <view class="em" @tap="chooseEmoji">    
                        <view class="icon biaoqing"></view>    
                    </view>    
                </view> -->  
            </view>  
            <!-- #ifndef H5 -->  
            <!-- <view class="more" @tap="showMore">    
                <view class="icon add"></view>    
            </view> -->  
            <!-- #endif -->  
            <!-- <view class="send" :class="isVoice?'hidden':''" @tap="sendText">    
                <view class="btn">发送</view>    
            </view> -->  
        </view>  
        <!-- 录音UI效果 -->  
        <view class="record" :class="recording?'':'hidden'">  
            <view class="ing" :class="willStop?'hidden':''">  
                <view class="icon luyin2"></view>  
            </view>  
            <view class="cancel" :class="willStop?'':'hidden'">  
                <view class="icon chehui"></view>  
            </view>  
            <view class="tis" :class="willStop?'change':''">{{recordTis}}</view>  
        </view>  
    </view>  
</template>  
<script>  
    export default {  
        data() {  
            return {  
                // 聊天页面时时滚动样式    
                style: {  
                    pageHeight: 0,  
                    contentViewHeight: 0,  
                    footViewHeight: 90,  
                    mitemHeight: 0  
                },  
                secondTouch: true,  
                // 确保websocket是打开状态    
                is_open_socket: false,  
                timer: '',  
                groupId: -1,  
                page: 1,  
                //文字消息    
                textMsg: '',  
                //消息列表    
                isHistoryLoading: false,  
                scrollAnimation: false,  
                scrollTop: 0,  
                scrollToView: '',  
                msgList: [],  
                msgImgList: [],  
                //myuid:0,    
                myuid: uni.getStorageSync("userId"),  
                //录音相关参数    
                // #ifndef H5    
                //H5不能录音    
                RECORDER: uni.getRecorderManager(),  
                // #endif    
                isVoice: false,  
                voiceTis: '按住 说话',  
                recordTis: "手指上滑 取消发送",  
                recording: false,  
                willStop: false,  
                initPoint: {  
                    identifier: 0,  
                    Y: 0  
                },  
                recordTimer: null,  
                recordLength: 0,  

                //播放语音相关参数    
                AUDIO: uni.createInnerAudioContext(),  
                playMsgid: null,  
                VoiceTimer: null,  
                // 抽屉参数    
                popupLayerClass: '',  
                // more参数    
                hideMore: true,  
                //表情定义    
                hideEmoji: true,  

                //红包相关参数    
                windowsState: '',  
                redenvelopeData: {  
                    rid: null, //红包ID    
                    from: null,  
                    face: null,  
                    blessing: null,  
                    money: null,  
                }  
            };  
        },  
        onReady() {  
            this.$nextTick(function() {  
                console.log('进入页面滚动到底部')  
                //进入页面滚动到底部    
                //this.scrollTop = 9999;    
setTimeout(() => {  
    this.scrollToView = 'bottom';  
})  
                this.$nextTick(function() {  
                    this.scrollAnimation = true;  
                });  
            });  
        },  
        created() {  
            const res = uni.getSystemInfoSync(); //获取手机可使用窗口高度     api为获取系统信息同步接口    
            this.style.pageHeight = res.windowHeight;  
            this.style.contentViewHeight = res.windowHeight - uni.getSystemInfoSync().screenWidth / 750 * (100) -  
                70; //像素   因为给出的是像素高度 然后我们用的是upx  所以换算一下     
            this.scrollToBottom(); //创建后调用回到底部方法    
        },  
        onLoad(option) {  
            uni.setNavigationBarTitle({ // 这里加载标题    
                title: option.groupName + '分组'  
            });  
            this.groupId = option.groupId;  
            // 进入这个页面的时候创建websocket连接【整个页面随时使用】    
            this.connectSocketInit();  
            this.timer = setInterval(this.xinTiao, 30000);  
            this.getMsgList();  
            //语音自然播放结束    
            this.AUDIO.onEnded((res) => {  
                this.playMsgid = null;  
            });  
            // #ifndef H5    
            //录音开始事件    
            this.RECORDER.onStart((e) => {  
                this.recordBegin(e);  
            })  
            //录音结束事件    
            this.RECORDER.onStop((e) => {  
                this.recordEnd(e);  
            })  
            // #endif    
        },  
        onShow() {  
            // this.scrollTop = 9999999;  

            //模板借由本地缓存实现发红包效果,实际应用中请不要使用此方法。    
            //    

        },  
        beforeDestroy() {  
            //this.closeSocket();    
        },  
        methods: {  
            /**  
             * 滚动到底部  
             * @param Number flag 方式   
             * @param String position 位置 (top,bottom)  
             */  
            ###newToBottom(flag = 0,position = 'bottom') {  
            ###  setTimeout(() => {  
            ###      if (flag) { //  方式一  
            ###        this.scrollToView = 'msg' + (position == 'top' ? 0 : this.msgList.length - 1);  
            ###        return  
            ###      }  
            ###      // 方式二  
            ###      this.scrollToView = '';  
            ###      this.scrollToView = position;  
            ###  })    
            ###},  
            /**    
             * @author gongliying    
             * @date 2019-07-26       https://www.cnblogs.com/gongliying/p/11258189.html    
             * @information 跳转页面底部    
             */  
            scrollToBottom: function() {  
                console.log('in scrollToBottom')  
                let that = this;  
                let query = uni.createSelectorQuery();  
                console.log('in scrollToBottom   2')  
                query.selectAll('.row').boundingClientRect();  
                query.select('#scrollview').boundingClientRect();  
                console.log('in scrollToBottom  3')  
                query.exec((res) => {  
                    console.log("得到布局位置信息:" + JSON.stringify(res));  
                    console.log("节点离页面顶部的距离为:" + res[0].top);  
                    that.style.mitemHeight = 0;  
                    res[0].forEach((rect) => {  
                        console.log('rect.height= ' + rect.height);  
                        that.style.mitemHeight = that.style.mitemHeight + rect.height + 40;  
                    })  
                    //获取所有内部子元素的高度    
                    // 因为vue的虚拟DOM 每次生成的新消息都是之前的,所以采用异步setTimeout    主要就是添加了这红字                            
                    setTimeout(() => {  
                        if (that.style.mitemHeight > (that.style.contentViewHeight -  
                                100)) { //判断子元素高度是否大于显示高度    
                            that.scrollTop = that.style.mitemHeight - that.style  
                                .contentViewHeight //用子元素的高度减去显示的高度就获益获得序言滚动的高度    
                        }  
                    }, 100);  

                })  
            },  
            xinTiao: function() {  
                //setInterval(this.run,5000);                   
                let _this = this;  
                let tempData = '{"type":"1","userid": "' + uni.getStorageSync("userId") + '"}';  
                console.log(tempData)  
                _this.socketTask.send({  
                    data: tempData, /// '{"type":"1","userid": '+uni.getStorageSync("userId")+'}',    
                    async success() {  
                        //console.log("消息发送成功");    
                    },  
                });  
            },  
            // 进入这个页面的时候创建websocket连接【整个页面随时使用】    
            connectSocketInit() {  
                // 创建一个this.socketTask对象【发送、接收、关闭socket都由这个对象操作】    
                this.socketTask = uni.connectSocket({  
                    // 【非常重要】必须确保你的服务器是成功的,如果是手机测试千万别使用ws://127.0.0.1:9099【特别容易犯的错误】    
                    url: 'ws://www.bjcn-tech.com:30190/vom/api/websocket/61', // 31',//'后台的地址', **例如:ws: '192.168.10.101:8080'**    
                    success(data) {  
                        console.log("websocket连接成功");  
                    },  
                });  

                // 消息的发送和接收必须在正常连接打开中,才能发送或接收【否则会失败】    
                this.socketTask.onOpen((res) => {  
                    console.log("WebSocket连接正常打开中...!");  
                    this.is_open_socket = true;  
                    this.xinTiao();  
                    // 注:只有连接正常打开中 ,才能正常成功发送消息    

                    /* this.socketTask.send({    
                        data:  '{"type":"2","userid":"118","groupid":"31","mp3":"uni-app发送一条消息222"}',    
                        async success() {    
                            console.log("消息发送成功");    
                        },    
                    }); */  
                    // 注:只有连接正常打开中 ,才能正常收到消息    
                    this.socketTask.onMessage((res) => {  
                        console.log("收到服务器内容:" + res.data);  
                        if (JSON.parse(res.data).type == "2") {  
                            console.log("收到服务器内容:" + res.data);  
                            console.log("收到服务器内容:" + typeof(JSON.parse(res.data).type));  
                            console.log("收到服务器内容:" + JSON.parse(res.data).userid + '****' + JSON.parse(  
                                res  
                                .data).username);  
                            console.log('in this.socketTask.onMessage((res)')  
                            var nowDate = new Date();  
                            let lastid = this.msgList[this.msgList.length - 1].msg.id;  
                            lastid++;  
                            if (JSON.parse(res.data).userid != uni.getStorageSync('userId')) {  
                                /* let msg = {type:'user',msg:{id:lastid,time:nowDate.getHours()+":"+nowDate.getMinutes(),type:'text',userinfo:{uid:JSON.parse(res.data).userid,username:"大黑哥",face:"/static/img/face.jpg"},content:res.data}} */  
                                let msg = {  
                                    type: 'user',  
                                    msg: {  
                                        id: lastid,  
                                        time: nowDate.getHours() + ":" + nowDate.getMinutes(),  
                                        type: 'voice',  
                                        userinfo: {  
                                            uid: JSON.parse(res.data).userid,  
                                            username: JSON.parse(res.data).username,  
                                            face: "/static/img/face.jpg"  
                                        },  
                                        content: JSON.parse(res.data).mp3  
                                    }  
                                } //username:"大黑哥"        content:res.data    
                                // uid 得改  username:"大黑哥"    
                                // 发送消息    
                                this.screenMsg(msg);  
                            }  
                        }  
                    });  
                })  
                // 这里仅是事件监听【如果socket关闭了会执行】    
                this.socketTask.onClose(() => {  
                    this.is_open_socket = false;  
                    console.log("已经被关闭了")  
                })  
            },  
            // 关闭websocket【离开这个页面的时候执行关闭】    
            /* closeSocket() {    
                this.socketTask.close({    
                    success(res) {    
                        this.is_open_socket = false;    
                        console.log("关闭成功", res)    
                    },    
                    fail(err) {    
                        console.log("关闭失败", err)    
                    }    
                })    
            }, */  
            // 离开也不关闭   20210516    
            // 接受消息(筛选处理)    
            screenMsg(msg) {  
                //从长连接处转发给这个方法,进行筛选处理    
                if (msg.type == 'system') {  
                    // 系统消息    
                    switch (msg.msg.type) {  
                        case 'text':  
                            this.addSystemTextMsg(msg);  
                            break;  
                        case 'redEnvelope':  
                            this.addSystemRedEnvelopeMsg(msg);  
                            break;  
                    }  
                } else if (msg.type == 'user') {  
                    // 用户消息    
                    switch (msg.msg.type) {  
                        case 'text':  
                            this.addTextMsg(msg);  
                            break;  
                        case 'voice':  
                            this.addVoiceMsg(msg);  
                            //this.addVoiceMsg(msg.msg.mp3);    
                            break;  
                        case 'img':  
                            this.addImgMsg(msg);  
                            break;  
                        case 'redEnvelope':  
                            this.addRedEnvelopeMsg(msg);  
                            break;  
                    }  
                    console.log('用户消息');  
                    //非自己的消息震动    
                    if (msg.msg.userinfo.uid != this.myuid) {  
                        console.log('振动');  
                        uni.vibrateLong();  
                        this.playVoice(msg.msg);  
                        /* const innerAudioContext = uni.createInnerAudioContext();    
                        innerAudioContext.autoplay = true;    
                        innerAudioContext.src = '/static/audio/6000.mp3';    
                        innerAudioContext.onPlay(() => {    
                          console.log('开始播放');    
                        });    
                        innerAudioContext.onError((res) => {    
                          console.log(res.errMsg);    
                          console.log(res.errCode);    
                        });  */  
                    }  
                }  
                this.$nextTick(function() {  
                    // 滚动到底    
                    ###this.newToBottom();  
                    console.log('this.scrollToView= in screenMsg' + this.scrollToView)  
                });  
            },  

            //触发滑动到顶部(加载历史信息记录)    
            loadHistory(e) {  
                //let that = this;                  
                console.log('in loadHistory')  
                if (this.isHistoryLoading) {  
                    return;  
                }  
                console.log('in loadHistory  2');  
                console.log(typeof(this.page))  
                this.page = this.page + 1;  
                console.log('前面的  ' + this.page);  
                this.isHistoryLoading = true; //参数作为进入请求标识,防止重复请求    
                this.scrollAnimation = false; //关闭滑动动画    
                let Viewid = this.msgList[0].msg.id; //记住第一个信息ID    
                //本地模拟请求历史记录效果    
                setTimeout(() => {  
                    // 消息列表    
                    /* let list = [    
                        {type:"user",msg:{id:1,type:"text",time:"12:56",userinfo:{uid:0,username:"大黑哥",face:"/static/img/face.jpg"},content:{text:"为什么温度会相差那么大?"}}},    
                        {type:"user",msg:{id:2,type:"text",time:"12:57",userinfo:{uid:1,username:"售后客服008",face:"/static/img/im/face/face_2.jpg"},content:{text:"这个是有偏差的,两个温度相差十几二十度是很正常的,如果相差五十度,那即是质量问题了。"}}},    
                        {type:"user",msg:{id:3,type:"voice",time:"12:59",userinfo:{uid:1,username:"售后客服008",face:"/static/img/im/face/face_2.jpg"},content:{url:"/static/voice/1.mp3",length:"00:06"}}},    
                        {type:"user",msg:{id:4,type:"voice",time:"13:05",userinfo:{uid:0,username:"大黑哥",face:"/static/img/face.jpg"},content:{url:"/static/voice/2.mp3",length:"00:06"}}},    
                    ] */  
                    console.log(uni.getStorageSync('userId'));  
                    console.log(this.groupId);  
                    console.log(this.page);  
                    uni.request({  
                        url: 'myUrl',  
                        data: {  
                            'userId': uni.getStorageSync('userId'), // 118,  432    
                            'chatGroupId': this.groupId, // 31 ,  62    
                            'page': this.page  
                        },  
                        /* this.$http.get('cgr/listChatMsgByChatGroupId', {    
                            'userId': uni.getStorageSync('userId'), // 118,  432    
                            'chatGroupId': this.groupId, // 31 ,  62    
                            'page': this.page    
                        }).then((res) => { */  
                        success: (res) => {  
                            var list = [];  
                            console.log(res);  
                            res = res.data;  
                            /* if(res.success == true && res.totalSize >0){ */  
                            if (res.success == true && res.data.length > 0) {  
                                var i = 0;  
                                /* for(;i<res.totalSize;i++){ */  
                                for (; i < res.data.length; i++) {  
                                    /* let jiLu = {type:"user",msg:{id:res.data[i].id,type:"voice",time:res.data[i].msgTime,userinfo:{uid:res.data[i].userId,username:res.data[i].userId,face:"/static/img/face.jpg"},content:{text:res.data[i].msgMacro}}} */ //username:"大黑哥"    
                                    let jiLu = {  
                                        type: "user",  
                                        msg: {  
                                            id: res.data[i].id,  
                                            type: "voice",  
                                            time: res.data[i].msgTime,  
                                            userinfo: {  
                                                uid: res.data[i].userId,  
                                                username: res.data[i].nickname,  
                                                face: "/static/img/face.jpg"  
                                            },  
                                            content: res.data[i].msgMacro  
                                        }  
                                    }  
                                    console.log(jiLu);  
                                    list.push(jiLu);  
                                }  
                            } else {  
                                this.scrollTop = 0;  
                                setTimeout(function() {  
                                    //_this.isRotate = false;    
                                    uni.showToast({  
                                        icon: 'none',  
                                        position: 'bottom',  
                                        title: '已经到底最顶端,上面没有了'  
                                    });  
                                }, 3000);  
                                this.$nextTick(function() {  
                                    this.scrollAnimation = false;  
                                });  
                            }  
                            //this.msgList = list;    
                            // 获取消息中的图片,并处理显示尺寸    
                            for (let i = 0; i < list.length; i++) {  
                                /* if(list[i].type=='user'&&list[i].msg.type=="img"){    
                                    list[i].msg.content = this.setPicSize(list[i].msg.content);    
                                    this.msgImgList.unshift(list[i].msg.content.url);    
                                }    
                                list[i].msg.id = Math.floor(Math.random()*1000+1); */  
                                this.msgList.unshift(list[i]);  
                            }  
                        }, //).catch((e) => {    
                        fail: (e) => {  
                            console.log(e);  
                            console.log(JSON.stringify(e));  
                            setTimeout(function() {  
                                //_this.isRotate = false;    
                                uni.showToast({  
                                    icon: 'none',  
                                    position: 'bottom',  
                                    title: '不行啊,请求超时,请稍后再试'  
                                });  
                            }, 3000);  
                        }  
                    });  

                    //这段代码很重要,不然每次加载历史数据都会跳到顶部    
                    this.$nextTick(function() {  
                        ###this.newToBottom(0,'top'); //跳转上次的第一行信息位置    
                        // this.scrollToView = 'msg' + Viewid; //跳转上次的第一行信息位置    
                        this.$nextTick(function() {  
                            this.scrollAnimation = true; //恢复滚动动画    
                        });  
                        console.log('this.scrollToView in loadHistory  ' + this.scrollToView)  
                    });  
                    this.isHistoryLoading = false;  

                }, 1000);  
            },  
            // 加载初始页面消息    
            getMsgList() {  
                //let list = [{type:"system",msg:{id:0,type:"text",content:{text:"欢迎进入  聊天室"}}},];    
                let list = [];  
                //for(var pageLinShi =1;pageLinShi<3;pageLinShi++){    
                /* this.$http.get('cgr/listChatMsgByChatGroupId', {    
                    'userId': uni.getStorageSync('userId'), // 118,  432    
                    'chatGroupId': this.groupId, // 31 ,  62    
                    'page': 1, //pageLinShi    
                }).then((res) => { */  
                uni.request({  
                    url: 'myUrl',  
                    data: {  
                        'userId': uni.getStorageSync('userId'), // 118,  432    
                        'chatGroupId': this.groupId, // 31 ,  62    
                        'page': 1  
                    },  
                    success: (res) => {  
                        console.log(res);  
                        /* if(res.success == true && res.totalSize >0){  */  
                        res = res.data;  
                        if (res.success == true && res.data.length > 0) {  
                            var i = 0;  
                            /* for(;i<res.totalSize;i++){ */  
                            for (; i < res.data.length; i++) {  
                                /* let jiLu = {type:"user",msg:{id:res.data[i].id,type:"text",time:res.data[i].msgTime,userinfo:{uid:res.data[i].userId,username:res.data[i].userId,face:"/static/img/face.jpg"},content:res.data[i].msgMacro}} */ //  username:"大黑哥"     
                                let jiLu = {  
                                    type: "user",  
                                    msg: {  
                                        id: res.data[i].id,  
                                        type: "voice",  
                                        time: res.data[i].msgTime,  
                                        userinfo: {  
                                            uid: res.data[i].userId,  
                                            username: res.data[i].nickname,  
                                            face: "/static/img/face.jpg"  
                                        },  
                                        content: res.data[i].msgMacro  
                                    }  
                                }  
                                //console.log(jiLu);    
                                list.unshift(jiLu);  
                                //this.msgList.unshift(jiLu);    
                            }  
                        }  
                    }, //).catch((e) => {    
                    fail: (e) => {  
                        console.log(e)  
                        console.log(JSON.stringify(e));  
                        setTimeout(function() {  
                            //_this.isRotate = false;    
                            uni.showToast({  
                                icon: 'none',  
                                position: 'bottom',  
                                title: '不行啊,请求超时,请稍后再试'  
                            });  
                        }, 3000);  

                    }  
                });  
                ///}    
                this.msgList = list;  
                // this.scrollToBottom();  
                // 滚动到底部    
                this.$nextTick(function() {  
                    console.log('进入页面滚动到底部')  
                    //进入页面滚动到底部    
                    //this.scrollTop = 9999;    
                    ###this.newToBottom();  
                    this.$nextTick(function() {  
                        this.scrollAnimation = true;  
                    });  
                });  
                //}     
                // 消息列表    
                //let list = [{type:"system",msg:{id:0,type:"text",content:{text:"欢迎进入HM-chat聊天室"}}},];    
                /* let list = [    
                    {type:"system",msg:{id:0,type:"text",content:{text:"欢迎进入HM-chat聊天室"}}},    
                    {type:"user",msg:{id:1,type:"text",time:"12:56",userinfo:{uid:0,username:"大黑哥",face:"/static/img/face.jpg"},content:{text:"为什么温度会相差那么大?"}}},    
                    {type:"user",msg:{id:2,type:"text",time:"12:57",userinfo:{uid:1,username:"售后客服008",face:"/static/img/im/face/face_2.jpg"},content:{text:"这个是有偏差的,两个温度相差十几二十度是很正常的,如果相差五十度,那即是质量问题了。"}}},    
                    {type:"user",msg:{id:3,type:"voice",time:"12:59",userinfo:{uid:1,username:"售后客服008",face:"/static/img/im/face/face_2.jpg"},content:{url:"/static/voice/1.mp3",length:"00:06"}}},    
                    {type:"user",msg:{id:4,type:"voice",time:"13:05",userinfo:{uid:0,username:"大黑哥",face:"/static/img/face.jpg"},content:{url:"/static/voice/2.mp3",length:"00:06"}}},    
                    {type:"user",msg:{id:5,type:"img",time:"13:05",userinfo:{uid:0,username:"大黑哥",face:"/static/img/face.jpg"},content:{url:"/static/img/p10.jpg",w:200,h:200}}},    
                    {type:"user",msg:{id:6,type:"img",time:"12:59",userinfo:{uid:1,username:"售后客服008",face:"/static/img/im/face/face_2.jpg"},content:{url:"/static/img/q.jpg",w:1920,h:1080}}},    
                    {type:"system",msg:{id:7,type:"text",content:{text:"欢迎进入HM-chat聊天室"}}},    

                    {type:"system",msg:{id:9,type:"redEnvelope",content:{text:"售后客服008领取了你的红包"}}},    
                    {type:"user",msg:{id:10,type:"redEnvelope",time:"12:56",userinfo:{uid:0,username:"大黑哥",face:"/static/img/face.jpg"},content:{blessing:"恭喜发财,大吉大利,万事如意",rid:0,isReceived:false}}},    
                    {type:"user",msg:{id:11,type:"redEnvelope",time:"12:56",userinfo:{uid:1,username:"售后客服008",face:"/static/img/im/face/face_2.jpg"},content:{blessing:"恭喜发财",rid:1,isReceived:false}}},    
                ] */  
                // 获取消息中的图片,并处理显示尺寸    
                /* for(let i=0;i<list.length;i++){    
                    if(list[i].type=='user'&&list[i].msg.type=="img"){    
                        list[i].msg.content = this.setPicSize(list[i].msg.content);    
                        this.msgImgList.push(list[i].msg.content.url);    
                    }    
                } */  

            },  

            //更多功能(点击+弹出)     
            showMore() {  
                this.isVoice = false;  
                this.hideEmoji = true;  
                if (this.hideMore) {  
                    this.hideMore = false;  
                    this.openDrawer();  
                } else {  
                    this.hideDrawer();  
                }  
            },  
            // 打开抽屉    
            openDrawer() {  
                this.popupLayerClass = 'showLayer';  
            },  
            // 隐藏抽屉    
            hideDrawer() {  
                this.popupLayerClass = '';  
                setTimeout(() => {  
                    this.hideMore = true;  
                    this.hideEmoji = true;  
                }, 150);  
            },  

            //获取焦点,如果不是选表情ing,则关闭抽屉    
            textareaFocus() {  
                if (this.popupLayerClass == 'showLayer' && this.hideMore == false) {  
                    this.hideDrawer();  
                }  
            },  
            // 发送文字消息    
            sendText() {  
                this.hideDrawer(); //隐藏抽屉    
                if (!this.textMsg) {  
                    return;  
                }  
                //let content = this.replaceEmoji(this.textMsg);    
                /* let content =this.textMsg;    
                let msg = {text:content}    
                this.sendMsg(msg,'text'); */  
                console.log('in sendText' + this.textMsg);  
                this.sendMsg(this.textMsg, 'text'); //只发文字    
                this.textMsg = ''; //清空输入框    
            },  

            // 发送消息    
            sendMsg(content, type) {  
                if (this.is_open_socket) {  
                    //var json = '{"type":"2","userid":"118","groupid":"31","mp3":"'+content+'"}';    
                    var json = '{"type":"2","userid":"' + 434 + '","username":"' + uni  
                        .getStorageSync("username") + '","groupid":"' + this.groupId + '","mp3":"' + content + '"}';  
                    console.log(json);  
                    // websocket的服务器的原理是:发送一次消息,同时返回一组数据【否则服务器会进去死循环崩溃】    
                    this.socketTask.send({  
                        data: json, //data要字符串!!!!    
                        //data:"关闭吗",    
                        async success() {  
                            console.log("消息发送成功");  
                        },  
                    });  
                    //message.isSend = true;    
                    //this.msgListMy.push(JSON.parse(json));    
                    //this.scrollBottom();    
                    //this.msg = ""    
                }  

                //实际应用中,此处应该提交长连接,模板仅做本地处理。    
                var nowDate = new Date();  
                let lastid = this.msgList[this.msgList.length - 1].msg.id;  
                lastid++;  
                let msg = {  
                    type: 'user',  
                    msg: {  
                        id: lastid,  
                        time: nowDate.getHours() + ":" + nowDate.getMinutes(),  
                        type: type,  
                        userinfo: {  
                            uid: 434,  
                            username: "大黑哥",  
                            face: "/static/img/face.jpg"  
                        },  
                        content: content  
                    }  
                }  
                // 发送消息    
                this.screenMsg(msg);  
                // 定时器模拟对方回复,三秒    
                /* setTimeout(()=>{    
                    lastid = this.msgList[this.msgList.length-1].msg.id;    
                    lastid++;    
                    msg = {type:'user',msg:{id:lastid,time:nowDate.getHours()+":"+nowDate.getMinutes(),type:type,userinfo:{uid:1,username:"售后客服008",face:"/static/img/im/face/face_2.jpg"},content:content}}    
                    // 本地模拟发送消息    
                    this.screenMsg(msg);    
                },3000) */  
            },  

            // 添加文字消息到列表    
            addTextMsg(msg) {  
                console.log('in addTextMsg,and msg = ' + msg)  
                this.msgList.push(msg);  
                this.$set(this.msgList, this.msgList.length - 1, this.msgList[this.msgList.length - 1]);  

                //debugger;    
                console.log(this.msgList[this.msgList.length - 1].msg.content)  
            },  
            // 添加语音消息到列表    
            addVoiceMsg(msg) {  
                this.msgList.push(msg);  
                this.$set(this.msgList, this.msgList.length - 1, this.msgList[this.msgList.length - 1]);  
                this.scrollToBottom();  

                //this.playVoice(msg.msg);    

            },  
            sendSystemMsg(content, type) {  
                let lastid = this.msgList[this.msgList.length - 1].msg.id;  
                lastid++;  
                let row = {  
                    type: "system",  
                    msg: {  
                        id: lastid,  
                        type: type,  
                        content: content  
                    }  
                };  
                this.screenMsg(row)  
            },  
            // 播放语音    
            playVoice(msg) {  
                console.log('in playVoice(msg)')  
                console.log('msg.id= ' + msg.id)  
                console.log('msg.content.url=' + msg.content)  
                console.log(msg)  

                this.playMsgid = msg.id;  
                //this.AUDIO.src = msg.content.url;    
                this.AUDIO.src = 'http://www.bjcn-tech.com:30180/uploadFiles/socketMp3/' + msg.content;  
                //if(this.secondTouch){    
                this.$nextTick(function() {  
                    this.AUDIO.play();  
                    this.secondTouch = false;  
                });  
                /* }else{    
                    this.AUDIO.stop();    
                    this.secondTouch= true;    
                } */  
            },  
            // 录音开始    
            voiceBegin(e) {  
                if (e.touches.length > 1) {  
                    return;  
                }  
                this.initPoint.Y = e.touches[0].clientY;  
                this.initPoint.identifier = e.touches[0].identifier;  
                this.RECORDER.start({  
                    format: "mp3"  
                }); //录音开始,    
            },  
            //录音开始UI效果    
            recordBegin(e) {  
                this.recording = true;  
                this.voiceTis = '松开 结束';  
                this.recordLength = 0;  
                this.recordTimer = setInterval(() => {  
                    this.recordLength++;  
                }, 1000)  
            },  
            // 录音被打断    
            voiceCancel() {  
                this.recording = false;  
                this.voiceTis = '按住 说话';  
                this.recordTis = '手指上滑 取消发送'  
                this.willStop = true; //不发送录音    
                this.RECORDER.stop(); //录音结束    
            },  
            // 录音中(判断是否触发上滑取消发送)    
            voiceIng(e) {  
                if (!this.recording) {  
                    return;  
                }  
                let touche = e.touches[0];  
                //上滑一个导航栏的高度触发上滑取消发送    
                if (this.initPoint.Y - touche.clientY >= uni.upx2px(100)) {  
                    this.willStop = true;  
                    this.recordTis = '松开手指 取消发送'  
                } else {  
                    this.willStop = false;  
                    this.recordTis = '手指上滑 取消发送'  
                }  
            },  
            // 结束录音    
            voiceEnd(e) {  
                if (!this.recording) {  
                    return;  
                }  
                this.recording = false;  
                this.voiceTis = '按住 说话';  
                this.recordTis = '手指上滑 取消发送'  
                this.RECORDER.stop(); //录音结束    
            },  
            //录音结束(回调文件)    
            recordEnd(e) {  
                clearInterval(this.recordTimer);  
                if (!this.willStop) {  
                    console.log("e: " + JSON.stringify(e));  
                    //console.log(this.uploadMp3Action(e));    
                    //var myFirstPromise =  this.uploadMp3Action(e);        
                    uni.showLoading({  
                        title: '录音上传中...'  
                    });  
                    const uploadTask = uni.uploadFile({  
                        url: 'myUrl',  
                        filePath: e.tempFilePath, //filePath,//录音结束后返回的临时路径    
                        //name: 'audio',    
                        name: 'file',  
                        success: (uploadFileRes) => {  
                            console.log(JSON.stringify(uploadFileRes.data));  
                            console.log(JSON.parse(uploadFileRes.data));  
                            console.log(JSON.parse(uploadFileRes.data).success)  
                            console.log(JSON.parse(uploadFileRes.data).data[0].appPath);  
                            if (JSON.stringify(uploadFileRes.data) != "" && JSON.parse(uploadFileRes.data)  
                                .success) {  
                                /* let msg = {    
                                    length:0,    
                                    url:JSON.parse(uploadFileRes.data).data[0].appPath,//e.tempFilePath    
                                }    
                                let min = parseInt(this.recordLength/60);    
                                let sec = this.recordLength%60;    
                                min = min<10?'0'+min:min;    
                                sec = sec<10?'0'+sec:sec;    
                                msg.length = min+':'+sec;     
                                this.sendMsg(msg,'voice');*/  
                                this.sendMsg(JSON.parse(uploadFileRes.data).data[0].appPath, 'voice');  
                            }  
                        },  
                        fail: (res) => {  
                            console.log(JSON.stringify(res));  
                        }  
                    });  
                    uni.hideLoading();  

                } else {  
                    console.log('取消发送录音');  
                }  
                this.willStop = false;  
            },  
            // 切换语音/文字输入    
            switchVoice() {  
                this.hideDrawer();  
                this.isVoice = this.isVoice ? false : true;  
            },  
            discard() {  
                return;  
            }  
        }  
    }  
</script>  
<style lang="scss">  
    @import "./HM-chat/css/style.scss";  
</style>  
  • jasonDev (作者)

    谢谢您的热心回复。可是我按照你的改了,还是不能满足需求啊。有时候能刷新出来,有时候又刷新不出来,不知道怎么回事。比如我发了10个语音消息,第4、7、8条语音就是没有刷新出来,但是可以播放出来。方便加qq吗?谢谢,不知道是不是跟我的心跳包有关系

    2021-05-30 13:11

  • DCMarvel

    回复 jasonDev: 我只说了新消息滚动到底/顶问题,并没有测试列表信息问题.列表不刷新自己打印list列表自己看就行了.有信息不显示 自己加this.$forceUpdate();

    2021-05-30 13:26

  • jasonDev (作者)

    回复 DCMarvel: 有时候收到消息有震动,但是不能自动播放,没有刷新到列表。郁闷。。。。。这种几率问题,最麻烦了。。。

    2021-05-30 14:12

jasonDev

jasonDev (作者) - 努力

// 添加语音消息到列表      
            addVoiceMsg(msg) {    
                this.msgList.push(msg);    
                this.$set(this.msgList, this.msgList.length - 1, this.msgList[this.msgList.length - 1]);  
                  this.$forceUpdate();  
                this.scrollToBottom();    

                //this.playVoice(msg.msg);      

            },  

我是这样添加语音消息到列表的,在demo中测试20次,没问题。可是整合到项目中,有时候出现接收方收不到消息的情况(记录里没显示,也没有播放),不知道什么原因?从后台看,我的语音已经上传到后台了(可以在浏览器播放)

  • DCMarvel

    接收方没消息

    1).WebSocket连接失败.

    2).WebSocket下发失败

    建议在WebSocket接收端输出日志查看

    2021-05-30 14:27

  • jasonDev (作者)

    回复 DCMarvel: 有震动,说明收到了。只是自动播放、自动刷新到底端不成功。说明还是前台代码有问题。真不知道到底哪里有问题。有时候又能自动播放、自动刷新到底部

    2021-05-30 14:44

DCMarvel

DCMarvel

// 添加语音消息到列表        
            addVoiceMsg(msg) {      
                this.msgList.push(msg);      
                //这行不要了,可能信息被复写了 push + forceUpdate就行 this.$set(this.msgList, this.msgList.length - 1, this.msgList[this.msgList.length - 1]);    
                  this.$forceUpdate();    
                this.scrollToBottom();      

                //this.playVoice(msg.msg);        

            },  
  • jasonDev (作者)

    改了,华为手机向小米手机发了10条,一条不正常;小米向华为发,只有3条正常。不行啊

    2021-05-30 15:18

该问题目前已经被锁定, 无法添加新回复