前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在线客服系统源码开发实战总结:需求分析及前端代码基本技术方案

在线客服系统源码开发实战总结:需求分析及前端代码基本技术方案

作者头像
唯一Chat
发布2022-11-18 13:43:17
9380
发布2022-11-18 13:43:17
举报
文章被收录于专栏:陶士涵的菜地陶士涵的菜地

在这个系列文章里,我尝试将自己开发唯一客服系统gofly.v1kf.com)所涉及的经验和技术点进行梳理总结。

文章写作水平有限,有时候会表达不清楚,难免有所疏漏,欢迎批评指正

该系列将分成以下几个部分

一. 需求分析

二. 初步技术方案选型,验证

三. 数据库结构设计

四. WEB访客前端设计与开发

五. WEB客服端设计与开发

六. 客户端设计与开发

在这个系列的文章中,您将了解并学习到以下技术知识:

MySQL、VUE、WebSocket、Golang+Gin、UniApp 等

如果这些技术对您有用,还请您 推荐 一下本文章,谢谢!

什么是在线客服系统

常见的用法是,点击立即咨询按钮,直接跳转到聊天窗口。或者是只需将系统生成的一段JavaScript代码嵌入网站页面,即可在网站上显示代表客服的浮动小图标,邀请框,点击按钮后在当前页面弹窗展示。

而客服端可以在WEB客服后台,查看网站正在沟通的实时在线访客、浏览轨迹等,能直接和网站访客进行在线即时交流,目的是提升客户满意度,及时解决客户的问题,进一步提升网站的销售额。

由此分析,在线客服系统大至分为三大块:1)访客端,2)客服端,3)客服移动端。但是仅仅分为这三大块是不够的,后面我们还将对每一块进行进一步的分析。

访客弹窗入口界面

访客端弹窗界面

前端界面是使用的elementui,是基于vue.js的UI框架。作为后端开发程序员,非常不习惯用node.js编译开发前端,所以我还是选择了使用cdn引入的形式去使用这个框架

弹窗效果是使用的layer.js进行的弹窗,点击图标,调用layer.js去iframe的形式加载了访客链接,这个访客链接就是下面直接打开时的效果

 访客端直接打开的界面

此界面为响应式设计,综合运用了css3的媒体查询功能,在大屏幕和小屏幕都能适配展示,所以该访客界面是可以直接接入微信和APP中。

这个界面可以说的还是比较多的,后面我再去详细总结

 客服端界面

 客服端也是使用的elementUI框架,整体结构是iframe框出来的,然后点击不同的菜单加载URL展示出来

总体来说,项目是偏向后端风格的,偏传统的架构

下面是访客端界面的代码,就可以看出这个工作量有多大~~

代码语言:javascript
复制
<!DOCTYPE html>
<head>
    <meta charset="utf-8">
    <!--删除苹果默认的工具栏和菜单栏,默认为no显示工具栏和菜单栏。-->
    <meta name="apple-mobile-web-app-capable" content="yes"/>
    <!--QQ强制全屏-->
    <meta name="x5-fullscreen" content="true">
    <!--UC强制全屏-->
    <meta name="fullscreen" content="yes">
    <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;" name="viewport" />
    <title>{{.Title}}</title>
    <link rel="stylesheet" href="/static/cdn/element-ui/2.15.1/theme-chalk/index.min.css">
    <script src="/static/cdn/vue/2.6.11/vue.min.js"></script>
    <script src="/static/cdn/element-ui/2.15.1/index.js"></script>
    <script src="/static/cdn/jquery/3.6.0/jquery.min.js"></script>

    <script src="/static/js/functions.js?v=0.6.9"></script>
    <link rel="stylesheet" href="/static/css/common.css?v=yuyfgfgfg" />
    <link rel="stylesheet" href="/static/css/icono.min.css" />
    <link rel="icon" href="/static/images/favicon.ico">
    <style>
        .el-message-box{
            width: auto;
            max-width: 100%;
            max-height: 100%;
            overflow: auto;
        }
    </style>
</head>
<body class="visitorBody">
<div id="app"  class="chatCenter">
    <template>
        <!--客服代码-->

        <div class="chatEntTitle" v-show="!isIframe">
            <el-badge :type="onlineType" is-dot class="item">
                <el-avatar class="chatEntTitleLogo" :size="35" :src="noticeAvatar"></el-avatar>
            </el-badge>
            <div>
                <div><{chatTitle}></div>
                <div class="entIntro" v-show="entIntroduce!=''"><{entIntroduce}></div>
            </div>
        </div>
        <div class="chatEntBox">
            <!--公告栏-->
            <div v-show="visitorNotice!=''"
                    class="visitorNotice"
                    >
                <img src='/static/images/laba.svg'/>
                <span><{visitorNotice}></span>
                <img v-on:click="visitorNotice=''" src="/static/images/cha.png" class="visitorNoticeClose"/>
            </div>
            <!--//公告栏-->


            <div  ref="chatVisitorPage" id="chatVisitorPage" class="chatContext chatVisitorPage" v-on:click="showIconBtns=false;showFaceIcon=false">
                <div class="chatBox">
                    <div class="chatNotice" v-on:click="loadMoreMessages" v-show="showLoadMore">
                        <a class="chatNoticeContent"><{flyLang.moremessage}></a>
                    </div>



                    <el-row :gutter="2" v-for="v in msgList" v-bind:class="{'chatBoxMe': v.is_kefu==true}">

                        <div class="messageBox questionBox" v-if="v.type=='question'">
                            <div class="chatTime left" v-bind:class="{'chatTimeHide': v.show_time==false}"><span><{v.time}></span></div>
                            <div class="left" v-if="v.is_kefu!=true" style="display: flex;">
                                <el-avatar style="margin-right:10px;flex-shrink: 0;"  :size="36" :src="v.avator"></el-avatar>
                                <div class="chatMsgContent">
                                    <div class="chatUser"  v-if="showKefuName!='off'"><{v.name}></div>
                                    <div class="chatContent chatContent2 replyContentBtn" v-html="v.content"></div>
                                </div>
                            </div>
                        </div>
                        <!--猜你想问-->
                        <div class="cardBox" v-else-if="v.type=='card'">
                            <div class='visitorReplyTitle'><{flyLang.guess}><a><i class='el-icon-refresh-left'></i> <{flyLang.huanyihuan}></a></div>
                            <div class="cardBoxContent" v-html="v.content"></div>
                        </div>
                        <!--//猜你想问-->

                        <!--消息模板-->
                        <div class="messageBox" v-else>
                            <div class="chatTime left" v-bind:class="{'chatTimeHide': v.show_time==false}"><span><{v.time}></span></div>
                            <div class="left" v-if="v.is_kefu!=true" style="display: flex;">
                                <el-avatar style="margin-right:10px;flex-shrink: 0;"  :size="36" :src="v.avator"></el-avatar>
                                <div class="chatMsgContent">
                                    <div class="chatUser"  v-if="showKefuName!='off'"><{v.name}></div>
                                    <div class="chatContent chatContent2 replyContentBtn" v-html="v.content"></div>
                                </div>
                            </div>
                            <div class="kefuMe right" v-if="v.is_kefu==true" style="display: flex;justify-content: flex-end;">
                                <div>
                                    <div class="chatContent chatContent2 replyContentBtn" v-html="v.content"></div>
                                    <div class="chatReadStatus" v-show="VisitorReadStatus!='true'"><{v.read_status}></div>
                                </div>
                                <el-avatar v-if="VisitorShowAvator=='true'" style="margin-left:10px;flex-shrink: 0;"  :size="36" :src="v.avator"></el-avatar>
                            </div>
                            <div class="clear"></div>
                        </div>
                        <!--//消息模板-->


                    </el-row>

                </div>
            </div>
            <div class="chatBoxSend">
                <div class="chatBoxSendMask" v-if="reconnectDialog">
                    <a @click="initConn" href="javascript:void(0);"><{flyLang.socketclose}></a>
                </div>

                <div class="hotQuestion" v-if="hotQuestion.length!=0">
                    <a
                            class="slideInRightItem"
                            v-for="item in hotQuestion"
                            v-on:click="messageContent=item;chatToUser()">
                        <{item}>
                    </a>
                </div>
                <!--进度条-->
                <div class="progressLine">
                    <el-progress :stroke-width="6"  :percentage="percentage" v-show="percentage!=0" :text-inside="true"></el-progress>
                </div>
                <!--//进度条-->
                <div class="iconBtns visitorIconBox">

                    <el-tooltip :content="flyLang.emotions" placement="top">
                        <div class="icono-smile visitorIconBtns visitorFaceBtn" v-on:click="showFaceIcon==true?showFaceIcon=false:showFaceIcon=true"></div>
                    </el-tooltip>
                    <el-tooltip :content="flyLang.photo" placement="top">
                        <div v-show="VisitorUploadImgBtn!='true'" :title="flyLang.photo" class="el-icon-picture" id="uploadImg" v-on:click="uploadImg('/uploadimg')" style="font-size: 22px;"></div>
                    </el-tooltip>
                    <el-tooltip :content="flyLang.file" placement="top">
                        <div v-show="VisitorUploadFileBtn!='true'" :title="flyLang.file" class="el-icon-upload" id="uploadFile" v-on:click="uploadFile('/2/uploadFile')" style="font-size: 22px;"></div>
                    </el-tooltip>
                    <el-tooltip :content="flyLang.recoder" placement="top">
                        <div v-show="VisitorVoiceBtn!='true'" :title="flyLang.recoder" class="el-icon-microphone"  v-on:click="audioDialog=true" style="font-size: 22px;"></div>
                    </el-tooltip>
                    <el-tooltip :content="flyLang.map" placement="top">
                        <div v-show="VisitorMapBtn!='true'" style="font-size: 22px;" class="el-icon-location"  v-on:click="qqMap==true?qqMap=false:qqMap=true;"></div>
                    </el-tooltip>
                    <el-tooltip :content="flyLang.audio" placement="top">
                        <div class="el-icon-phone-outline" @click="callPhone()" style="font-size: 20px;">
                        </div>
                    </el-tooltip>
                    <el-tooltip :content="flyLang.video" placement="top">
                        <div class="el-icon-video-camera" @click="callPeer()" style="font-size: 22px;">
                        </div>
                    </el-tooltip>
                    <el-tooltip :content="flyLang.language" placement="top">
                        <div  @click="flagsDialog='true'">
                            <img src="/static/images/lang.png" style="width: 20px;"/>
                        </div>
                    </el-tooltip>
                </div>
                <div class="faceBox visitorFaceBox" v-if="showFaceIcon">
                    <ul class="faceBoxList">
                        <li v-on:click="faceIconClick(i)" class="faceIcon" v-for="(v,i) in face"  :title="v.name"><img :src=v.path></li>
                    </ul>
                    <div class="clear"></div>
                </div>
                <!--搜索建议-->
                <div class="searchList" v-show="searchList.length!=0">
                    <div v-on:click="messageContent=item.title;chatToUser();searchList=[]" class="searchItem" v-for="item in searchList" v-html="item.htmlTitle"></div>
                </div>
                <!--//搜索建议-->
                <div class="visitorEditor">
{{/*                    <div v-if="VisitorVoiceBtn!='true'"  v-on:click="audioDialog==true?audioDialog=false:audioDialog=true" class="visitorEditorVoice visitorFaceBtn"></div>*/}}
                    <el-input :placeholder="flyLang.textarea" show-word-limit :maxlength="VisitorMaxLength" :rows="2" type="textarea" resize="none" class="visitorEditorArea"  @focus="scrollBottom;showIconBtns=false" @blur="scrollBottom;showIconBtns=false" v-model="messageContent"  @keyup.native="inputNextText" v-on:keyup.enter.native="chatToUser">
                    </el-input>
{{/*                    <div v-if="VisitorFaceBtn!='true'" :title="flyLang.emotions" v-on:click="showIconBtns==true?showIconBtns=false:showIconBtns=true" class="visitorEditorSmile visitorFaceBtn"></div>*/}}
{{/*                    <div v-if="VisitorUploadImgBtn!='true'&&VisitorPlusBtn=='true'" class="icono-image visitorEditorImg" id="uploadImg" v-on:click="uploadImg('/uploadimg')"></div>*/}}
{{/*                    <div v-if="VisitorPlusBtn!='true'" v-on:click="showIconBtns==true?showIconBtns=false:showIconBtns=true" v-show="messageContent==''" :title="flyLang.emotions" class="visitorEditorChoose"></div>*/}}
                </div>
                <el-button type="primary" size="mini"  class="visitorEditorBtn"   :disabled="sendDisabled||messageContent==''" v-on:click="chatToUser();showIconBtns=false"><{flyLang.sent}></el-button>

                <div class="footContact clear">
                    <a href="{{.CopyrightUrl}}" target="_blank">{{.CopyrightTxt}}</a>
                </div>
            </div>
        </div>
        <div class="chatArticle">
            <div style="padding: 8px;"><img style="width: 100%" :src="entInfo.intro_pic" v-if="entInfo.intro_pic" :title="entInfo.username"/></div>
            <h3 class="hotQuestionTitle">
                <img src="/static/images/fire.svg" class="fire"/><{flyLang.hotQuestionTitle}>
            </h3>
            <ul>
                <li v-on:click="messageContent=item;chatToUser()" class="chatArticleItem" v-for="item in topQuestionList"><a><{item}></a></li>
            </ul>
        </div>
        <div class="clear"></div>

        <!--//客服代码-->
        <audio id="chatMessageAudio">
            <source id="chatMessageAudioSource"  />
        </audio>
        <audio id="chatMessageSendAudio">
            <source id="chatMessageSendAudioSource"  />
        </audio>


        <!--图片预览-->

        <el-image
                style="display: none;"
                ref="preview"
                class="hideImgDiv"
                :src="imgPreviewSrc[0]"
                :preview-src-list="imgPreviewSrc"
                z-index="9999"
        ></el-image>


        <!--评价-->
        <el-dialog
                center
                :title="flyLang.visitorCommentTitle"
                :close-on-click-modal="false"
                width="90%"
                :visible.sync="comment"
        >
            <div class="commentBox">
                <div style="line-height: 25px;"><{flyLang.commentDesc}></div>
                <el-rate v-model="commentScore" style="margin-bottom: 30px;"></el-rate>
                <el-input
                        type="textarea"
                        :rows="4"
                        v-model="commentContent">
                </el-input>
{{/*                <el-tooltip content="good" placement="top">*/}}
{{/*                    <span class="icono-smile" v-on:click="sendComment('good');comment = false"></span>*/}}
{{/*                </el-tooltip>*/}}
{{/*                <el-tooltip content="normal" placement="top">*/}}
{{/*                <span class="icono-meh" v-on:click="sendComment('normal');comment = false"></span>*/}}
{{/*                </el-tooltip>*/}}
{{/*                <el-tooltip content="bad" placement="top">*/}}
{{/*                <span class="icono-frown" v-on:click="sendComment('bad');comment = false"></span>*/}}
{{/*                </el-tooltip>*/}}
            </div>
            <span slot="footer" class="dialog-footer">
                <el-button type="primary"  v-on:click="sendComment();comment = false"><{flyLang.sent}></el-button>
            </span>
        </el-dialog>
        <!--//评价-->
        <!--地图-->
        <iframe v-if="qqMap" style="position: fixed;top: 0;left: 0;z-index: 999999999" id="mapPage" width="100%" height="100%" frameborder=0
                src="https://apis.map.qq.com/tools/locpicker?search=1&type=1&key=
OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77&referer=kefu">
        </iframe>
        <!--//地图-->
        <el-dialog
                :title="flyLang.leave"
                :visible.sync="allOffline"
                width="100%"
                top="0">
            <el-input style="margin-bottom: 10px;" :placeholder="flyLang.email"  v-model="visitorContact.email"></el-input>
            <el-input style="margin-bottom: 10px;" :placeholder="flyLang.wechat"  v-model="visitorContact.weixin"></el-input>
            <el-input style="margin-bottom: 10px;" :placeholder="flyLang.realname"  v-model="visitorContact.name"></el-input>
            <el-input :placeholder="flyLang.content" type="textarea"  v-model="visitorContact.msg"></el-input>
            <span slot="footer" class="dialog-footer">
                        <el-button @click="sendEmailMsg"><{flyLang.sent}></el-button>
                        <el-button @click="allOffline = false"><{flyLang.cancel}></el-button>
                    </span>
        </el-dialog>
        <!--录音-->
        <el-dialog
                :visible.sync="audioDialog"
                width="100%"
        >
            <div class="dialogRecoder">
                <el-progress :color="colors" type="dashboard" :format="recoderFormat" :stroke-width="10" :percentage="recoderSecond"></el-progress>
                <br/>
                <audio v-show="recorderEnd" controls ref="audio" muted="muted" src="" id="audio"></audio>
                <br/>
                <el-button id="start" @click="startRecoder($event)" size="small" type="primary"><{flyLang.start}></el-button>
                <el-button @click="stopRecoder($event)" size="small" type="warning"><{flyLang.stop}></el-button>
                <el-button @click="cancelRecoder()" size="small" type="danger"><{flyLang.cancel}></el-button>
                <el-button @click="sendRecoder()" size="small" type="success"><{flyLang.sent}></el-button>
            </div>

        </el-dialog>
        <!--//录音-->
        <!--切换语言-->
        <el-dialog
                :visible.sync="flagsDialog"
                width="90%"
                top="30px">
            <el-button @click="selectLang('cn')" class="flagBtn" type="primary" plain>中文简体</el-button>
            <el-button @click="selectLang('tw')" class="flagBtn" type="primary" plain>中文繁体</el-button>
            <el-button @click="selectLang('en')" class="flagBtn" type="primary" plain>English</el-button>
        </el-dialog>
        <!--//切换语言-->
        <!--录音-->
        <!--视频-->
        <el-dialog
                center
                :close-on-click-modal="false"
                :visible="isCalling"
                width="90%"
                :show-close="false"
                @opened="initCallingDialog"
                >
            <video id="chatRtc" style="width: 100%;"  controls autoplay></video>
            <video v-if="isVideo==true" id="chatLocalRtc" style="width: 100%;" controls  muted></video>
            <span slot="footer" class="dialog-footer">
                <el-button @click="callClose()" type="danger" size="mini">挂断</el-button>
              </span>
        </el-dialog>
        <!--//录音-->

    </template>
</div>
</body>
<script src="/static/js/xss.js"></script>
<script src="/static/js/reconnecting-websocket.min.js"></script>
<script src="/static/js/recoder.js"></script>
<script src="/static/js/audio.js"></script>
<script>
    var KEFU_ID='{{.KEFU_ID}}';
    var REFER=urlDecode('{{.Refer}}');
    var REFER_URL=urlDecode('{{.ReferUrl}}');
    var ENT_ID='{{.ENT_ID}}';
    var IS_TRY='{{.IS_TRY}}';
    var VISITOR_ID='{{.visitorId}}';
    var VISITOR_NAME='{{.visitorName}}';
    var ERR_MSG='{{.errMsg}}';
    var AVATOR='{{.avator}}';
    var LANG=checkLang();
    var SHOW_KEFU_NAME='{{.ShowKefuName}}';
    var EXTRA='{{.Extra}}';
</script>
<script src="/static/js/chat-lang.js?v=dsdsdgf45hkjk"></script>
<script src="/static/js/chat-config.js?v=0.5.1"></script>
<script src="/static/js/peer.js"></script>
<script>
    new Vue({
        el: '#app',
        delimiters:["<{","}>"],
        data: {
            window:window,
            server:getWsBaseUrl()+"/ws_visitor",
            socket:null,
            msgList:[],
            imgPreviewSrc:[
                ""],
            msgListNum:[],
            messageContent:"",
            chatTitle:KEFU_LANG[LANG]['connecting'],
            visitor:{},
            face:emojiGifsMap(),
            showKfonline:false,
            socketClosed:false,
            focusSendConn:false,
            wsSocketClosed:true,
            timer:null,
            loadingTimer:null,
            sendDisabled:false,
            entLogo:"",
            entName:"",
            peer:null,
            peerjsId:"",
            kefuPeerId:"",
            loading:null,
            localStream:null,
            flyLang:KEFU_LANG[LANG],
            lang:LANG,
            textareaFocused:false,
            replys:[],
            noticeName:"",
            noticeAvatar:"",
            allOffline:false,
            visitorContact:{
                email:"",
                weixin:"",
                name:"",
                msg:"",
            },
            haveUnreadMessage:false,
            audioDialog:false,
            flagsDialog:false,
            recorder:null,
            recorderAudio:null,
            recordeTimer:null,
            recoderSecond:0,
            currentActiveTime:Date.now(),
            timeoutTimer:null,
            timeoutLongTime:20*60*1000,//20分钟没反应
            allTimeouter:[],
            currentPage:1,
            showLoadMore:false,
            loadMoreDisable:false,
            websocketOpenNum:0,//websocket打开次数
            websocketMaxOpenNum:10,//websocket最大打开次数
            talkBtnText:"按住 说话",
            recorderEnd:false,
            isMobile:false,
            isIframe:false,
            onlineType:"success",
            reconnectDialog:false,
            showIconBtns:false,
            showFaceIcon:false,
            showKefuName:SHOW_KEFU_NAME,
            comment:false,
            qqMap:false,
            hotQuestion:[],
            topQuestionList:[],
            topQuestionCount:0,
            topQuestionPage:1,
            topQuestionPagesize:5,
            entIntroduce:"",
            robotSwitch:"",
            robotNoAnswer:"",
            visitorNotice:"",
            autoWelcome:"",
            searchList:[],
            VisitorVoiceBtn:'{{.VisitorVoiceBtn}}',
            VisitorMapBtn:'{{.VisitorMapBtn}}',
            VisitorCommentBtn:'{{.VisitorCommentBtn}}',
            VisitorFaceBtn:'{{.VisitorFaceBtn}}',
            VisitorReadStatus:'{{.VisitorReadStatus}}',
            VisitorPlusBtn:'{{.VisitorPlusBtn}}',
            VisitorUploadImgBtn:'{{.VisitorUploadImgBtn}}',
            VisitorUploadFileBtn:'{{.VisitorUploadFileBtn}}',
            VisitorMaxLength:'{{.VisitorMaxLength}}'==''?100:parseInt('{{.VisitorMaxLength}}'),
            VisitorShowAvator:'{{.VisitorShowAvator}}',
            VisitorWechatQrcodeUrl:'{{.VisitorWechatQrcodeUrl}}',
            percentage:0,
            visitorMaxNumLimit:false,//客服达到接待上限
            visitorMaxNumNotice:"",//客服达到接待上限文案
            visitorCookie:"",
            scanWechatQrcode:"",
            entConfig:{},
            colors: [
                {color: '#f56c6c', percentage: 20},
                {color: '#e6a23c', percentage: 40},
                {color: '#5cb87a', percentage: 60},
                {color: '#1989fa', percentage: 80},
                {color: '#6f7ad3', percentage: 100}
            ],
            commentScore:0,
            commentContent:"",
            isCalling:false,
            call:null,
            videoElement:null,
            canvasElement:null,
            isVideo:false,
            entInfo:{},
        },
        methods: {
            //初始化websocket
            initConn:function() {
                this.socket = new ReconnectingWebSocket(this.server+"?visitor_id="+this.visitor.visitor_id+"&to_id="+this.visitor.to_id);//创建Socket实例
                this.socket.debug = true;
                this.socket.onmessage = this.OnMessage;
                this.socket.onopen = this.OnOpen;
                this.socket.onerror = this.OnError;
                this.socket.onclose = this.OnClose;
                this.ping();
            },
            OnOpen:function() {
                console.log("ws:onopen");
                //限制最大打开次数
                if(this.websocketOpenNum>=this.websocketMaxOpenNum){
                    this.chatTitle=KEFU_LANG[LANG]['refresh'];
                    this.socket.close();
                    return;
                }
                this.websocketOpenNum++;

                this.chatTitle=this.noticeName;
                this.checkTimeout();
                this.socketClosed=false;
                this.focusSendConn=false;
                this.wsSocketClosed=false;
                this.sendVisitorLogin();
                this.getExtendInfo();
                this.reconnectDialog=false;
                this.showTitle(KEFU_LANG[LANG]['connectok']);
                this.getNotice();

            },
            OnMessage:function(e) {
                console.log("ws:onmessage");
                this.socketClosed=false;
                this.focusSendConn=false;
                const redata = JSON.parse(e.data);
                if (redata.type == "kfOnline") {
                    let msg = redata.data
                    if(this.showKfonline && this.visitor.to_id==msg.id){
                        return;
                    }
                    this.visitor.to_id=msg.id;
                    this.chatTitle=msg.name+","+KEFU_LANG[LANG]['chating'];
                    $(".chatBox").append("<div class=\"chatTime\">"+this.chatTitle+"</div>");
                    this.scrollBottom();
                    this.showKfonline=true;
                }
                if (redata.type == "transfer") {
                    var kefuId = redata.data
                    if(!kefuId){
                        return;
                    }
                    this.visitor.to_id=kefuId;
                }
                if (redata.type == "comment") {
                    this.comment=true;
                }
                if (redata.type == "wechat_notice") {
                    this.showTitle(KEFU_LANG[LANG]['wechatNotice']);
                }
                if (redata.type == "notice") {
                    let msg = redata.data
                    if(!msg){
                        return;
                    }
                    this.chatTitle=msg
                    $(".chatBox").append("<div class=\"chatTime\">"+this.chatTitle+"</div>");
                    this.scrollBottom();
                }
                if (redata.type == "accept") {
                    var _this=this;
                    let msg = redata.data;
                    if(!msg||_this.localStream==null){
                        return;
                    }
                    // this.$confirm('请求与您通话?', '提示', {
                    //     confirmButtonText: '确定',
                    //     cancelButtonText: '取消',
                    //     type: 'warning'
                    // }).then(() => {
                        _this.kefuPeerId=msg;
                        _this.isCalling=true;
                    // }).catch(() => {
                    // });

                }
                if (redata.type == "callPhone") {
                    this.callPhone();
                }
                if (redata.type == "callVideo") {
                    this.callPeer();
                }
                if (redata.type == "refuse") {
                    this.$message({
                        message: "已挂断",
                        type: 'error'
                    });
                    this.callClear();
                    return;
                }
                if (redata.type == "delete") {
                    var msg = redata.data;
                    for(var i=0;i<this.msgList.length;i++){
                        if(this.msgList[i].msg_id==msg.msg_id){
                            this.msgList.splice(i,1);
                            break;
                        }
                    }
                }
                if (redata.type == "read") {
                    var msg = redata.data;
                    for(var i=0;i<this.msgList.length;i++){
                        this.msgList[i].read_status=KEFU_LANG[LANG]['read'];
                    }
                }
                if (redata.type == "message") {
                    let msg = redata.data
                    //this.visitor.to_id=msg.id;
                    var _this=this;

                    var msgArr=msg.content.split("[br]");
                    for(var i in msgArr){
                        let content = {}
                        content.avator = msg.avator;
                        content.name = msg.name;
                        content.content =replaceSpecialTag(msgArr[i]);
                        content.is_kefu = false;
                        content.time = shortTime(msg.time);
                        content.is_reply=true;
                        content.msg_id = msg.msg_id;
                        this.msgList.push(content);
                        setTimeout(function () {
                            _this.scrollBottom();
                        },200);
                    }

                    // let content = {}
                    // content.avator = msg.avator;
                    // content.name = msg.name;
                    // content.content =replaceSpecialTag(msg.content);
                    // content.is_kefu = false;
                    // content.time = msg.time;
                    // content.msg_id = msg.msg_id;
                    // this.msgList.push(content);

                    notify(msg.name, {
                        body: msg.content,
                        icon: msg.avator
                    },function(notification) {
                        window.focus();
                        notification.close();
                    });
                    //this.scrollBottom();
                    flashTitle();//标题闪烁
                    //clearInterval(this.timer);
                    this.cleanAllTimeout();
                    this.alertSound('/static/images/alert4.mp3');//提示音
                    this.haveUnreadMessage=true;
                }
                if (redata.type == "close") {
                    this.showTitle(KEFU_LANG[LANG]['closemes']);
                    this.scrollBottom();
                    this.socket.close();
                    //this.socketClosed=true;
                    this.focusSendConn=true;
                    this.reconnectDialog=true;
                }
                if (redata.type == "force_close") {
                    this.showTitle(KEFU_LANG[LANG]['forceclosemes']);
                    this.scrollBottom();
                    this.socket.close();
                    this.socketClosed=true;
                    this.reconnectDialog=true;
                }
                if (redata.type == "auto_close") {
                    this.showTitle(KEFU_LANG[LANG]['autoclosemes']);
                    this.scrollBottom();
                    this.socket.close();
                    this.socketClosed=true;
                    this.reconnectDialog=true;
                }
                if (redata.type == "change_id") {
                    var openId = redata.data;
                    setFakeCookie("visitor_"+ENT_ID,openId,this.visitorCookie);
                    location.reload();
                }
                window.parent.postMessage(redata,"*");
            },
            //发送给客户
            chatToUser:function() {
                this.searchList=[];
                if(this.sendDisabled){
                    return;
                }
                var messageContent=this.messageContent.trim("\r\n");
                messageContent=messageContent.replace("\n","");
                messageContent=messageContent.replace("\r\n","");
                messageContent=filterXSS(messageContent);
                if(messageContent==""||messageContent=="\r\n"){
                    this.messageContent="";
                    return;
                }
                this.messageContent="";
                this.currentActiveTime=Date.now();
                if(this.socketClosed){
                    this.initConn();
                    // this.$message({
                    //     message: '连接关闭!请重新打开页面',
                    //     type: 'warning'
                    // });
                    //return;
                }
                this.sendDisabled=true;
                let _this=this;

                let content = {}
                content.avator=_this.visitor.avator;
                content.content = replaceSpecialTag(messageContent);
                content.name = _this.visitor.name;
                content.is_kefu = true;
                content.time = _this.getNowDate();
                content.show_time=false;

                let mes = {};
                mes.type = "visitor";
                mes.content = messageContent;
                mes.from_id = this.visitor.visitor_id;
                mes.to_id = this.visitor.to_id;

                //机器人回答
                if(this.robotSwitch=="true"){
                    this.sendDisabled=false;
                    this.messageContent="";
                    //转接人工,没用处于排队状态
                    if(this.turnToMan && this.turnToMan.includes(mes.content)){
                        if(this.visitorMaxNumLimit){
                            this.showTitle(this.visitorMaxNumNotice);
                            return;
                        }
                        this.initConn();
                        this.robotSwitch="";
                    }else{
                        content.read_status = KEFU_LANG[LANG]['read'];
                        _this.msgList.push(content);
                        _this.scrollBottom();
                        _this.sendAjax("/2/robotMessage","post",{ent_id:ENT_ID,content:messageContent},function(msg){
                            if(msg.content==""){
                                msg.content=_this.robotNoAnswer;
                            }
                            if(msg.content==""){
                                return;
                            }
                            let content = {}
                            content.avator=msg.avator;
                            content.content = replaceSpecialTag(msg.content);
                            content.name = msg.username;
                            content.is_kefu = false;
                            content.read_status = KEFU_LANG[LANG]['read'];
                            content.time = _this.getNowDate();
                            content.show_time=false;
                            _this.msgList.push(content);
                            _this.scrollBottom();
                        });
                        return;
                    }
                }
                content.read_status = KEFU_LANG[LANG]['unread'];
                _this.msgList.push(content);
                _this.scrollBottom();

                //发送人工消息
                $.post("/2/message?lang="+getQuery("lang"),mes,function(res){
                    _this.sendDisabled=false;
                    if(res.code!=200){
                        _this.$message({
                            message: res.msg,
                            type: 'error'
                        });
                        if(res.code==401){
                            setTimeout(function(){
                                window.location.reload();
                            },2000);
                        }
                        return;
                    }
                    var result=res.result
                    if(result.isBlack){
                        _this.msgList.pop();
                        content.content=result.content;
                        _this.msgList.push(content);
                    }

                    _this.messageContent = "";
                    _this.cleanAllTimeout();
                    _this.sendSound();
                    _this.sendDisabled=false;
                });

            },
            //正在输入
            inputNextText:function(){
                var _this=this;
                this.sendInputingStrNow(this.messageContent);
                //是否进行搜索
                if(this.robotSwitch!="true"){
                    return;
                }
                this.sendAjax("/2/searchQuestion","get",{ent_id:ENT_ID,content:this.messageContent},function(res){
                    result=res.result;
                    if(!result){
                        return;
                    }
                    for(key in result){
                        var str=result[key].title;
                        str= str.replace(_this.messageContent,"<span>"+_this.messageContent+"</span>");
                        result[key].htmlTitle=str;
                    }
                    _this.searchList=result;
                });
            },
            sendInputingStrNow:function(str){
                if(this.socketClosed||!this.socket||this.wsSocketClosed){
                    return;
                }
                var message = {}
                message.type = "inputing";
                message.data = {
                    from : this.visitor.visitor_id,
                    to : this.visitor.to_id,
                    content:str
                };
                this.socket.send(JSON.stringify(message));
            },
            sendVisitorLogin:function(){
                var _this=this;
                setTimeout(function(){
                    if(_this.socketClosed||!_this.socket||_this.wsSocketClosed){
                        return;
                    }
                    var message = {}
                    message.type = "visitor_login";
                    message.data = {
                        from : _this.visitor.visitor_id,
                        to : _this.visitor.to_id,
                    };
                    _this.socket.send(JSON.stringify(message));
                }, 3000);
            },
            OnClose:function(event) {
                console.log("ws:onclose",event);
                this.focusSendConn=true;
                this.wsSocketClosed=true;
                this.closeTimeoutTimer();
            },
            OnError:function(event) {
                console.log("ws:onerror",event);
                this.closeTimeoutTimer();
            },
            //获取当前用户信息
            getUserInfo:function(){
                var _this=this;
                var visitor_id=getFakeCookie("visitor_"+ENT_ID);
                var to_id=KEFU_ID;


                var extra=EXTRA;
                var url=getQuery("url");
                var paramVisitorId=VISITOR_ID;
                if(paramVisitorId!=""){
                    visitor_id=paramVisitorId;
                }
                var visitorName=VISITOR_NAME;
                var avator=AVATOR;

                if(extra==""){
                    var ext={};
                    var refer=document.referrer?document.referrer:"-";
                    ext.refer=refer;
                    ext.host=document.location.href;
                    extra=utf8ToB64(JSON.stringify(ext));
                }else{
                    try{
                        var jsonStr=b64ToUtf8(extra)
                        var extJson=JSON.parse(jsonStr)
                        if(extJson.refer){
                            if(REFER=="") REFER=extJson.refer;
                            if(REFER_URL=="") REFER_URL=extJson.refer;
                        }
                    }catch (e) {}

                }
                if(REFER_URL==""){
                    REFER_URL=document.referrer;
                }
                if(REFER==""){
                    REFER=document.title;
                }
                //发送消息
                $.ajax({
                    type: "post",
                    url: "/visitor_login",
                    data:{visitor_id:visitor_id,
                        visitor_name:visitorName,
                        avator:avator,
                        refer:REFER,
                        to_id:to_id,
                        extra:extra,
                        ent_id:ENT_ID,
                        url:document.location.href,
                        refer_url:REFER_URL,
                        title:document.title
                    },
                    error:function(res){
                        var data=JSON.parse(res.responseText);
                        _this.$message({
                            message: data.msg,
                            type: 'error'
                        });
                    },
                    success: function(res) {
                        if(res.code==40012){
                            _this.$message({
                                message: res.msg,
                                type: 'error'
                            });
                            _this.chatTitle=res.msg;
                            _this.sendDisabled=true;
                            return;
                        }
                        if(res.code==40016){
                            _this.$message({
                                message: KEFU_LANG[LANG]['freqLimit'],
                                type: 'error'
                            });
                            _this.chatTitle=KEFU_LANG[LANG]['freqLimit'];
                            _this.sendDisabled=true;
                            return;
                        }
                        _this.entInfo=res.kefu;
                        _this.noticeName=res.kefu.username;
                        _this.noticeAvatar=res.kefu.avatar;
                        _this.robotNoAnswer=res.robotNoAnswer;
                        _this.getTopQuestion();


                        //判断同时接待访客数
                        if(res.code==40018){
                            _this.visitorMaxNumLimit=true;
                            _this.visitor=res.result;
                            _this.robotSwitch="true";
                            _this.chatTitle=_this.noticeName;
                            _this.turnToMan=res.turnToMan.split(",");
                            var visitorMaxNumNotice=res.visitorMaxNumNotice;
                            if(visitorMaxNumNotice==""){
                                visitorMaxNumNotice="当前有"+res.visitorMaxNum+"位访客正在咨询,请稍等一会再尝试&nbsp;<a href='javascript:window.location.reload();'>刷新</a>";
                            }
                            _this.visitorMaxNumNotice=visitorMaxNumNotice;
                            _this.showTitle(visitorMaxNumNotice);
                            _this.sendDisabled=true;
                            return;
                        }

                        if(res.code!=200){
                            _this.$message({
                                message: res.msg,
                                type: 'error'
                            });
                            _this.chatTitle=res.msg;
                            _this.sendDisabled=true;
                            return;
                        }
                        if(res.alloffline){
                            _this.onlineType="danger";
                        }else{
                            _this.onlineType="success";
                        }
                        if(KEFU_CONFIG.SHOW_OFFLINE_PAGE){
                            _this.allOffline=res.alloffline;
                        }
                        _this.sendDisabled=false;
                        _this.visitor=res.result;
                        _this.noticeName=res.kefu.username;
                        _this.noticeAvatar=res.kefu.avatar;
                        _this.entIntroduce=res.entIntroduce;
                        _this.robotSwitch=res.robotSwitch;
                        _this.turnToMan=res.turnToMan.split(",");
                        _this.chatTitle=_this.noticeName;
                        _this.visitorNotice=res.visitorNotice;
                        _this.autoWelcome=res.autoWelcome;
                        _this.visitorCookie=res.visitorCookie;
                        _this.scanWechatQrcode=res.scanWechatQrcode;
                        document.title=res.kefu.username;
                        if(!getFakeCookie("visitor_"+ENT_ID)){
                            setFakeCookie("visitor_"+ENT_ID,_this.visitor.visitor_id,res.visitorCookie);
                        }

                        _this.loadMoreMessages();
                        _this.showWechatTip();
                        if(_this.robotSwitch!="true"){
                            _this.initConn();
                        }
                    }
                });

            },
            //获取信息列表
            getMesssagesByVisitorId:function(isAll){
                let _this=this;
                $.ajax({
                    type:"get",
                    url:"/2/messages?visitor_id="+this.visitor.visitor_id,
                    success: function(data) {
                        if(data.code==200 && data.result!=null&&data.result.length!=0){
                            let msgList=data.result;
                            _this.msgList=[];
                            for(var i=0;i<msgList.length;i++){
                                let visitorMes=msgList[i];
                                let content = {}
                                if(visitorMes["mes_type"]=="kefu"){
                                    content.is_kefu = false;
                                }else{
                                    content.is_kefu = true;
                                }
                                content.avator = visitorMes["avator"];
                                content.name = visitorMes["name"];
                                content.content = replaceContent(visitorMes["content"]);
                                content.time = visitorMes["time"];
                                _this.msgList.push(content);
                                _this.scrollBottom();
                            }
                        }
                        if(data.code!=200){
                            _this.$message({
                                message: data.msg,
                                type: 'error'
                            });
                            _this.chatTitle=KEFU_LANG[LANG]['refresh'];
                        }
                    }
                });
            },
            //获取信息列表
            sendEmailMsg:function(){
                let _this=this;
                _this.visitorContact.ent_id=ENT_ID;
                $.ajax({
                    type:"post",
                    url:"/ent/email_message",
                    data:_this.visitorContact,
                    success: function(data) {
                        if(data.code!=200){
                            _this.$message({
                                message: data.msg,
                                type: 'error'
                            });
                        }else{
                            _this.allOffline=false;
                        }
                    }
                });
            },
            //滚动到底部
            scrollBottom:function(){
                var _this=this;
                //$('.chatVisitorPage').animate({scrollTop:'99999999999999'},"slow");
                this.$nextTick(function(){
                    var container = _this.$el.querySelector(".chatVisitorPage");
                    container.scrollTop = 999999;
                    //alert(1);
                    //$('.chatVisitorPage').animate({scrollTop:'99999999999999'},'99999999');
                    // $('.chatVisitorPage').scrollTop(9999999999999999999);
                });
            },
            //软键盘问题
            textareaFocus:function(){
                // if(/Android|webOS|iPhone|iPad|BlackBerry/i.test(navigator.userAgent)) {
                //     //$(".chatContext").css("margin-bottom","0");
                //     //$(".chatBoxSend").css("position","static");
                //     this.textareaFocused=true;
                // }
                this.scrollBottom();
            },
            textareaBlur:function(){
                // if(this.textareaFocused&&/Android|webOS|iPhone|iPad|BlackBerry/i.test(navigator.userAgent)) {
                //     var chatBoxSendObj=$(".chatBoxSend");
                //     var chatContextObj=$(".chatContext");
                //     if(this.textareaFocused&&chatBoxSendObj.css("position")!="fixed"){
                //         //chatContextObj.css("margin-bottom","105px");
                //         //chatBoxSendObj.css("position","fixed");
                //         this.textareaFocused=false;
                //     }
                //
                // }
                this.scrollBottom();
            },
            sendReply:function(title){
                var _this=this;

                let msg = {}
                msg.avator=_this.visitor.avator;
                msg.content = replaceContent(title);
                msg.name = _this.visitor.name;
                msg.is_kefu = true;
                msg.time = _this.getNowDate();
                msg.show_time=false;
                _this.msgList.push(msg);
                _this.scrollBottom();

                var mes = {};
                mes.content = title;
                mes.from_id = this.visitor.visitor_id;
                mes.ent_id = ENT_ID;
                _this.sendAjax("/2/message_ask","post",mes,function(msg){
                    var msgArr=msg.content.split("[b]");
                    for(var i in msgArr){
                        let content = {}
                        content.avator = msg.avator;
                        content.name = msg.name;
                        content.content =replaceSpecialTag(msgArr[i]);
                        content.is_kefu = false;
                        content.time = msg.time;
                        content.is_reply=true;
                        _this.msgList.push(content);
                        _this.scrollBottom();
                    }
                    _this.cleanAllTimeout();
                    _this.alertSound('/static/images/notification.mp3');//提示音
                });
                //this.chatToUser();
            },
            //获取日期
            getNowDate : function() {// 获取日期
                var d = new Date(new Date());
                return d.getFullYear() + '-' + this.digit(d.getMonth() + 1) + '-' + this.digit(d.getDate())
                    + ' ' + this.digit(d.getHours()) + ':' + this.digit(d.getMinutes()) + ':' + this.digit(d.getSeconds());
            },
            //补齐数位
            digit : function (num) {
                return num < 10 ? '0' + (num | 0) : num;
            },
            setCache : function (key,obj){
                if(navigator.cookieEnabled&&typeof window.localStorage !== 'undefined'){
                    localStorage.setItem(key, JSON.stringify(obj));
                }
            },getCache : function (key){
                if(navigator.cookieEnabled&&typeof window.localStorage !== 'undefined') {
                    return JSON.parse(localStorage.getItem(key));
                }
            },
            setNoticeWelcome(list){
                var _this=this;
                var msgs = list;
                var delaySecond=0;
                for(let i in msgs){
                    var msg=msgs[i];
                    if(msg.delay_second){
                        delaySecond+=msg.delay_second;
                    }else{
                        delaySecond+=4;
                    }
                    var timer =  setTimeout(function (msg) {
                        msg.time=shortTime(getNowDate());
                        msg.content = replaceSpecialTag(msg.content);
                        msg.name=_this.entConfig.robotName;
                        _this.msgList.push(msg);
                        _this.scrollBottom();
                        _this.alertSound('/static/images/notification.mp3');
                        var redata={
                            type:"message",
                            data:msg
                        }
                        window.parent.postMessage(redata,"*");
                    },1000*delaySecond,msg);
                    _this.allTimeouter.push(timer);
                }
            },
            //获取自动欢迎语句
            getNotice : function (){
                var _this=this;
                var oldNotice=getFakeCookie("noticed_"+ENT_ID);
                if(oldNotice){
                    if(_this.autoWelcome=="on"){
                        return;
                    }
                    $.get("/2/notices?visitor_id="+this.visitor.visitor_id+"&ent_id="+ENT_ID+"&kefu_name="+this.visitor.to_id,function(res) {
                        _this.entConfig=res.result.ent_config;
                        if (res.result.welcome != null) {
                            setFakeCookie("noticed_"+ENT_ID,res.result.welcome,7*3600*24);
                            _this.setNoticeWelcome(res.result.welcome);
                        }
                    });
                    return;
                }
                $.get("/2/notices?is_record=1&visitor_id="+this.visitor.visitor_id+"&ent_id="+ENT_ID+"&kefu_name="+this.visitor.to_id,function(res) {
                    _this.entConfig=res.result.ent_config;
                    if (res.result.welcome != null) {
                        setFakeCookie("noticed_"+ENT_ID,res.result.welcome,7*3600*24);
                        _this.setNoticeWelcome(res.result.welcome);
                    }
                });
            },
            initCss:function(){
                var _hmt = _hmt || [];
                (function() {
                    var hm = document.createElement("script");
                    hm.src = "https://hm.baidu.com/hm.js?82938760e00806c6c57adee91f39aa5e";
                    var s = document.getElementsByTagName("script")[0];
                    s.parentNode.insertBefore(hm, s);
                })();

                var _this=this;
                $(function () {
                    //手机端的样式问题
                    // if(_this.isMobile){
                    //     $(".chatVisitorPage").css("height","calc(100% - 155px)");
                    // }
                    //展示表情
                    // var faces=placeFace();
                    // $.each(faceTitles, function (index, item) {
                    //     _this.face.push({"name":item,"path":faces[item]});
                    // });
                    // $(".visitorFaceBtn").click(function(e){
                    //     var status=$('.faceBox').css("display");
                    //     if(status=="block"){
                    //         $('.faceBox').hide();
                    //     }else{
                    //         $('.faceBox').show();
                    //     }
                    //     return false;
                    // });
                    $("body").on("click",".replyContentBtn a",function() {
                        var txt=$(this).text();
                        var href=$(this).attr("href");
                        if(href=="self"||!href){
                            _this.messageContent=txt;
                            _this.chatToUser();
                            return false;
                        }
                    });

                    //var windheight = $(window).height();
                    $(window).resize(function(){
                        //var docheight = $(window).height();  /*唤起键盘时当前窗口高度*/
                        //_this.scrollBottom();
                        _this.visitorPageHeight();
                        // if(docheight < windheight){            /*当唤起键盘高度小于未唤起键盘高度时执行*/
                        //     $(".chatBoxSend").css("position","static");
                        // }else{
                        //     $(".chatBoxSend").css("position","fixed");
                        // }
                        //_this.visitorPageHeight();
                        //document.getElementById('chatVisitorPage').style.height = (document.documentElement.clientHeight - 71) + 'px';
                    });
                    if(isMobile()){
                        _this.visitorPageHeight();
                        //document.getElementById('chatVisitorPage').style.height = (document.documentElement.clientHeight - 71) + 'px';
                    }
                    //自动问答
                    $("body").on("click",".visitorReplyContent",function() {
                        var txt=$(this).find("span").text();
                        _this.messageContent=txt;
                        _this.chatToUser();
                    });
                    //自动问答换一换
                    $("body").on("click",".visitorReplyTitle a",function() {
                        ++_this.topQuestionPage;
                        if(_this.topQuestionPage>_this.topQuestionCount){
                            _this.topQuestionPage=1;
                        }
                        var result=pagination(_this.topQuestionPage,_this.topQuestionPagesize,_this.topQuestionList);
                        _this.makeReplyItem(result,true);
                    });
                });
            },
            //心跳
            ping:function(){
                let _this=this;
                let mes = {}
                mes.type = "ping";
                mes.data = "visitor:"+_this.visitor.visitor_id;
                setInterval(function () {
                    if(_this.socket!=null&&!_this.wsSocketClosed){
                        _this.socket.send(JSON.stringify(mes));
                    }
                },10000);
            },
            //初始化
            init:function(){
                var _this=this;
                _this.isMobile=isMobile();

                this.initCss();
                //已读消息
                var ms= 1000*2;
                var lastClick = Date.now() - ms;
                $("body").mouseover(function(){
                    if(!_this.haveUnreadMessage){
                        return;
                    }
                    if (Date.now() - lastClick >= ms) {
                        lastClick = Date.now();
                        //如果有未读消息,调用已读接口
                        _this.sendAjax("/2/messages_read","post",{"visitor_id":_this.visitor.visitor_id,"kefu":_this.visitor.to_id},function(data){
                            _this.haveUnreadMessage=false;
                        });
                    }
                });
                $('body').click(function(){
                    clearFlashTitle();
                    window.parent.postMessage({type:"focus"},"*");
                    //$('.faceBox').hide();
                    //剪贴板
                    try{
                        var selecter = window.getSelection().toString();
                        if (selecter != null && selecter.trim() != ""){
                            var str=selecter.trim();
                            _this.sendInputingStrNow(str);
                        }
                    } catch (err){
                        var selecter = document.selection.createRange();
                        var s = selecter.text;
                        if (s != null && s.trim() != ""){
                            var str=s.trim();
                            _this.sendInputingStrNow(str);
                        }
                    }
                });



                $("body").on("click",".chatImagePic",function() {
                    var url=$(this).attr("data-src");
                    _this.imgPreviewSrc=[url];
                    _this.$refs.preview.clickHandler();
                    //new PinchZoom.default($(this)[0], {});
                    // _this.$alert("<img src='"+url+"'/>", "", {
                    //     dangerouslyUseHTMLString: true
                    // });
                    return false;
                });
                window.onfocus = function () {
                    //_this.focusHandle();
                }


                //判断当前是否在iframe中
                if(self!=top){
                    _this.isIframe=true;
                }

            },
            //表情点击事件
            faceIconClick:function(index){
                this.showFaceIcon=false;
                this.messageContent+="face"+this.face[index].name;
            },
            //上传图片
            uploadImg:function (url){
                let _this=this;
                $('#uploadImg').after('<input type="file" accept="image/gif,image/jpeg,image/jpg,image/png" id="uploadImgFile" name="file" style="display:none" >');
                $("#uploadImgFile").click();
                $("#uploadImgFile").change(function (e) {
                    var formData = new FormData();
                    var file = $("#uploadImgFile")[0].files[0];
                    formData.append("imgfile",file); //传给后台的file的key值是可以自己定义的
                    filter(file) && $.ajax({
                        url: url || '',
                        type: "post",
                        data: formData,
                        contentType: false,
                        processData: false,
                        dataType: 'JSON',
                        mimeType: "multipart/form-data",
                        //添加自定义属性,监听上下文的进度
                        xhr: function() {
                            //创建原生的ajax请求对象
                            var xhr = $.ajaxSettings.xhr();
                            //监听进度的一个事件
                            xhr.upload.onprogress = function(e) {
                                console.log(e.total); //文件大小
                                console.log(e.loaded); //上传多少
                                var w = parseInt((e.loaded / e.total) * 100)
                                console.log(w);
                                _this.percentage=w;
                                if(w>=100){
                                    _this.percentage=0;
                                }
                            }
                            return xhr
                        },
                        success: function (res) {
                            if(res.code!=200){
                                _this.$message({
                                    message: res.msg,
                                    type: 'error'
                                });
                            }else{
                                _this.$message({
                                    message: KEFU_LANG[LANG]['uploadSuccess'],
                                    type: 'success'
                                });
                                _this.messageContent+='img[' + res.result.path + ']';
                                _this.chatToUser();
                                setTimeout(function () {
                                    _this.scrollBottom();
                                },2000);
                            }
                        },
                        error: function (data) {
                            console.log(data);
                            _this.$message({
                                message: KEFU_LANG[LANG]['uploadFailed']+data.responseText,
                                type: 'error'
                            });
                        }
                    });
                });
            },
            //上传文件
            uploadFile:function (url){
                let _this=this;
                $('#uploadFile').after('<input type="file"  id="uploadRealFile" name="file2" style="display:none" >');
                $("#uploadRealFile").click();
                $("#uploadRealFile").change(function (e) {
                    var formData = new FormData();
                    var file = $("#uploadRealFile")[0].files[0];
                    formData.append("realfile",file); //传给后台的file的key值是可以自己定义的
                    console.log(formData);
                    $.ajax({
                        url: url || '',
                        type: "post",
                        data: formData,
                        contentType: false,
                        processData: false,
                        dataType: 'JSON',
                        mimeType: "multipart/form-data",
                        //添加自定义属性,监听上下文的进度
                        xhr: function() {
                            //创建原生的ajax请求对象
                            var xhr = $.ajaxSettings.xhr();
                            //监听进度的一个事件
                            xhr.upload.onprogress = function(e) {
                                console.log(e.total); //文件大小
                                console.log(e.loaded); //上传多少
                                var w = parseInt((e.loaded / e.total) * 100)
                                console.log(w);
                                _this.percentage=w;
                                if(w>=100){
                                    _this.percentage=0;
                                }
                            }
                            return xhr
                        },
                        success: function (res) {

                            if(res.code!=200){
                                _this.$message({
                                    message: res.msg,
                                    type: 'error'
                                });
                            }else{
                                _this.$message({
                                    message: KEFU_LANG[LANG]['uploadSuccess'],
                                    type: 'success'
                                });
                                //_this.messageContent+='file[' + res.result.path + ']';
                                var data=JSON.stringify({
                                    name:res.result.name,
                                    ext:res.result.ext,
                                    size:res.result.size,
                                    path:res.result.path,
                                })
                                _this.messageContent+='mutiFile[' + data+ ']';
                                _this.chatToUser();
                            }
                        },
                        error: function (data) {
                            console.log(data);
                            _this.$message({
                                message: KEFU_LANG[LANG]['uploadFailed']+data.responseText,
                                type: 'error'
                            });
                        }
                    });
                });
            },
            //粘贴上传图片
            onPasteUpload:function(event){
                let items = event.clipboardData && event.clipboardData.items;
                let file = null
                if (items && items.length) {
                    // 检索剪切板items
                    for (var i = 0; i < items.length; i++) {
                        if (items[i].type.indexOf('image') !== -1) {
                            file = items[i].getAsFile()
                        }
                    }
                }
                if (!file) {
                    return;
                }
                let _this=this;
                var formData = new FormData();
                formData.append('imgfile', file);
                $.ajax({
                    url: '/uploadimg',
                    type: "post",
                    data: formData,
                    contentType: false,
                    processData: false,
                    dataType: 'JSON',
                    mimeType: "multipart/form-data",
                    //添加自定义属性,监听上下文的进度
                    xhr: function() {
                        //创建原生的ajax请求对象
                        var xhr = $.ajaxSettings.xhr();
                        //监听进度的一个事件
                        xhr.upload.onprogress = function(e) {
                            console.log(e.total); //文件大小
                            console.log(e.loaded); //上传多少
                            var w = parseInt((e.loaded / e.total) * 100)
                            console.log(w);
                            _this.percentage=w;
                            if(w>=100){
                                _this.percentage=0;
                            }
                        }
                        return xhr
                    },
                    success: function (res) {
                        if(res.code!=200){
                            _this.$message({
                                message: res.msg,
                                type: 'error'
                            });
                        }else{
                            _this.$message({
                                message: KEFU_LANG[LANG]['uploadSuccess'],
                                type: 'success'
                            });
                            _this.messageContent+='img[' + res.result.path + ']';
                            _this.chatToUser();
                            setTimeout(function () {
                                _this.scrollBottom();
                            },2000);
                        }
                    },
                    error: function (data) {
                        console.log(data);
                        _this.$message({
                            message: KEFU_LANG[LANG]['uploadFailed']+data.responseText,
                            type: 'error'
                        });
                    }
                });
            },
            //自动
            getTopQuestion:function(){
                var _this=this;
                $.get("/other/getTopQuestion?ent_id="+ENT_ID,function(res) {
                    if(res.code!=200||!res.result){
                        return;
                    }
                    var hotQuestion=res.result.hotQuestion;
                    if(hotQuestion!=""){
                        _this.hotQuestion=hotQuestion.split(",");
                    }

                    var questionList=res.result.questionList;
                    if(questionList.length==0){
                        return;
                    }
                    _this.topQuestionList=questionList;
                    _this.topQuestionCount=sumPage(_this.topQuestionPagesize,questionList);
                    var result=pagination(1,_this.topQuestionPagesize,questionList);

                    _this.makeReplyItem(result);
                });
            },
            makeReplyItem:function(result,isPage){
                var _this=this;
                var msg={};
                msg.type="card";
                msg.avator = _this.noticeAvatar;
                msg.name = _this.noticeName;
                msg.show_time = true;
                msg.time = _this.getNowDate();
                msg.content="";
                var i=1;
                for(key in result){
                    msg.content+="<div class='visitorReplyContent'>"+i+". <span>"+result[key]+"</span></div>";
                    i++;
                }
                if(!isPage){
                    _this.msgList.push(msg);
                    _this.scrollBottom();
                }else{
                    $(".cardBoxContent").html(msg.content);
                }

            },
            //自动
            getAutoReply:function(){
                var _this=this;
                $.get("/autoreply?ent_id="+ENT_ID,function(res) {
                    if(res.code!=200 || res.result.length==0){
                        return;
                    }
                    var result=res.result;
                    _this.replys.push(result);
                });
            },
            //提示音
            alertSound:function(soundUrl){
                var b = document.getElementById("chatMessageAudio");
                if (b.canPlayType('audio/ogg; codecs="vorbis"')) {
                    b.type= 'audio/mpeg';
                    b.src=soundUrl ;
                    var p = b.play();
                    p && p.then(function () {
                    }).catch(function (e) {
                    });
                }
            },
            sendSound:function(){
                var b = document.getElementById("chatMessageSendAudio");
                if (b.canPlayType('audio/ogg; codecs="vorbis"')) {
                    b.type= 'audio/mpeg';
                    b.src= '/static/images/sent.ogg';
                    var p = b.play();
                    p && p.then(function(){}).catch(function(e){});
                }
            },
            initPeerjs:function(){
                var peer = new Peer();
                this.peer=peer;
                var _this=this;

                peer.on('open', function(id) {
                    console.log('My peer ID is: ' + id);
                    _this.peerjsId=id;
                });
                peer.on('close', function() {
                    console.log('My peer close');
                    if(_this.loading!=null){
                        _this.loading.close();
                    }
                });
                peer.on('disconnected', function() {
                    console.log('My peer disconnected');
                    if(_this.loading!=null){
                        _this.loading.close();
                    }
                });
                peer.on('error', function() {
                    console.log('My peer error');
                    if(_this.loading!=null){
                        _this.loading.close();
                    }
                });
            },
            //打电话
            callPhone:function(){
                var _this=this;
                var media=(navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia);
                if(!media){
                    _this.$message({
                        type: 'error',
                        message: "not support"
                    });
                    return ;
                }
                var getUserMedia = media.bind(navigator);
                this.$confirm(this.flyLang.videoAudio, this.flyLang.tips, {
                    confirmButtonText: this.flyLang.audio,
                    cancelButtonText: this.flyLang.cancel,
                    type: 'warning'
                }).then(() => {
                    _this.messageContent="voice call...";
                    _this.chatToUser();
                    _this.loading = _this.$loading({
                        lock: true,
                        text: _this.flyLang.connecting,
                        spinner: 'el-icon-phone-outline',
                        background: 'rgba(0, 0, 0, 0.7)'
                    });
                    _this.initPeerjs();//初始化peerjs
                    _this.loadingTimerTimeoutClose();
                    _this.isVideo=false;
                    getUserMedia({video:false, audio: {
                            noiseSuppression: true,
                            echoCancellation: true,
                        }}, function(stream) {
                        _this.localStream=stream;
                        _this.sendAjax("/2/callKefu","post",{"action":"callpeer",kefu_id:_this.visitor.to_id,visitor_id:_this.visitor.visitor_id},function(result){
                        });
                    }, function(err) {
                        _this.$message({
                            type: 'error',
                            message: err
                        });
                        if(_this.loading) _this.loading.close();
                    });
                }).catch(() => {
                });
            },
            callPeer:function(){
                var _this=this;
                var media=(navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia);
                if(!media){
                    _this.$message({
                        type: 'error',
                        message: "not support"
                    });
                    return ;
                }
                var getUserMedia = media.bind(navigator);
                this.$confirm(this.flyLang.videoAudio, this.flyLang.tips, {
                    confirmButtonText: this.flyLang.video,
                    cancelButtonText: this.flyLang.cancel,
                    type: 'warning'
                }).then(() => {
                    _this.messageContent="video call...";
                    _this.chatToUser();
                    this.loading = this.$loading({
                        lock: true,
                        text: _this.flyLang.connecting,
                        spinner: 'el-icon-video-camera',
                        background: 'rgba(0, 0, 0, 0.5)'
                    });
                    this.loadingTimerTimeoutClose();
                    this.isVideo=true;
                    //初始化peerjs
                    this.initPeerjs();
                    getUserMedia({video:true, audio: {
                            noiseSuppression: true,
                            echoCancellation: true,
                        }}, function(stream) {
                        _this.localStream=stream;
                        _this.sendAjax("/2/callKefu","post",{"action":"callpeer",kefu_id:_this.visitor.to_id,visitor_id:_this.visitor.visitor_id},function(result){
                        });
                    }, function(err) {
                        _this.$message({
                            type: 'error',
                            message: err
                        });
                        if(_this.loading) _this.loading.close();
                    });
                }).catch(() => {
                });
            },
            talkPeer:function(){
                var _this=this;
                var canvas = this.canvasElement;

                if(this.loading!=null){
                    this.loading.close();
                }
                clearTimeout(this.loadingTimer);
                this.$message({
                    message: '正在通话...',
                    type: 'success'
                });
                if(_this.kefuPeerId==""||_this.localStream==null){
                    return;
                }
                //本人摄像头
                if(_this.isVideo){
                    var localVideo=document.querySelector("#chatLocalRtc");
                    localVideo.srcObject = _this.localStream;
                    localVideo.autoplay=true;
                }

                //localVideo.autoplay = true;

                _this.call = _this.peer.call(_this.kefuPeerId, _this.localStream);
                _this.call.on('stream', function(remoteStream) {
                    var remoteVideo = document.querySelector("#chatRtc");
                    remoteVideo.srcObject = remoteStream;
                    remoteVideo.autoplay = true;
                });
                _this.call.on('close', function() {
                    console.log("call close");
                    _this.loading.close();
                    _this.callClear();
                });
                _this.call.on('error', function(err) {
                    console.log(err);
                    _this.callClear();
                    _this.loading.close();
                });
                // _this.$alert('正在通话,请保持页面..', '提示', {
                //     confirmButtonText: '挂断',
                //     callback: function(){
                //         _this.sendAjax("/2/callKefu","post",{"action":"callCancel",kefu_id:_this.visitor.to_id,visitor_id:_this.visitor.visitor_id},function(result){
                //         });
                //         if(call!=null){
                //             call.close();
                //         }
                //     }
                // });
                // 调用Vudio

                // var vudio = new Vudio(_this.localStream, canvas, {
                //     accuracy: 256,
                //     width: 800,
                //     height: 100,
                //     waveform: {
                //         fadeSide: false,
                //         maxHeight: 100,
                //         verticalAlign: 'middle',
                //         horizontalAlign: 'center',
                //         color: '#2980b9'
                //     }
                // })
                //
                // vudio.dance()

            },
            callClose(){
                var _this=this;
                if(this.call==null) return;
                _this.sendAjax("/2/callKefu","post",{"action":"callCancel",kefu_id:_this.visitor.to_id,visitor_id:_this.visitor.visitor_id},function(result){
                });
                _this.callClear();
            },
            getExtendInfo:function(){
                var _this=this;
                var extra=getQuery("extra");
                if(extra==""){
                    return;
                }

                try{
                    var extraString=b64ToUtf8(extra);
                    if(_this.getCache("extra")==extraString){
                        return;
                    }
                    var extra=JSON.parse(extraString);
                    if (typeof extra=="string"){
                        extra=JSON.parse(extra);
                    }

                    for(var key in extra){
                        if(extra[key]==""){
                            extra[key]="无";
                        }
                        if(key=="visitorProduct"){
                            _this.messageContent="product["+JSON.stringify(extra[key])+"]";
                            _this.chatToUser();
                            _this.setCache("extra",extraString);
                        };
                    }
                }catch (e) {
                }
            },
            sendAjax:function(url,method,params,callback){
                let _this=this;
                $.ajax({
                    type: method,
                    url: url,
                    data:params,
                    headers:{
                        "lang":getQuery("lang"),
                    },
                    error:function(res){
                        var data=JSON.parse(res.responseText);
                        console.log(data);
                        if(data.code!=200){
                            _this.$message({
                                message: data.msg,
                                type: 'error'
                            });
                        }
                    },
                    success: function(data) {
                        if(data.code!=200){
                            _this.$message({
                                message: data.msg,
                                type: 'error'
                            });
                        }else if(data.result!=null){
                            callback(data.result);
                        }else{
                            callback(data);
                        }
                    }
                });
            },
            showTitle:function(title){
                //this.chatTitle=title;
                $(".chatBox").append("<div class=\"chatNotice\"><div class='chatNoticeContent'>"+title+"</div></div>");
                this.scrollBottom();
            },
            //开始录音
            startRecoder:function(e){
                if(this.recorder){
                    this.recorder.destroy();
                    this.recorder=null;
                }
                var _this=this;
                Recorder.getPermission().then(function() {
                    _this.recorder = new Recorder();
                    _this.recorderAudio = document.querySelector('#audio');
                    _this.recorder.start();
                    _this.recorder.onprogress = function (params) {
                        _this.recoderSecond = parseInt(params.duration);
                    }
                    this.talkBtnText = "松开 结束";
                }, function(error){
                    _this.$message({
                        message: error,
                        type: 'error'
                    });
                    return;
                });
                e.preventDefault();
            },
            stopRecoder:function(e){
                if(!this.recorder){
                    return;
                }
                var blob=this.recorder.getWAVBlob();
                this.recorderAudio.src = URL.createObjectURL(blob);
                this.recorderAudio.controls = true;
                this.talkBtnText="按住 说话";
                this.recorderEnd=true;
                e.preventDefault();
            },
            sendRecoder:function(){
                if(!this.recorder){
                    return;
                }

                var blob=this.recorder.getWAVBlob();
                var formdata = new FormData(); // form 表单 {key:value}
                formdata.append("realfile", blob); // form input type="file"
                var _this=this;
                this.loading = this.$loading({
                    lock: true,
                    text: '正在发送',
                    spinner: 'el-icon-loading',
                    background: 'rgba(0, 0, 0, 0.7)'
                });
                $.ajax({
                    url: "/2/uploadAudio",
                    type: 'post',
                    processData: false,
                    contentType: false,
                    data: formdata,
                    dataType: 'JSON',
                    mimeType: "multipart/form-data",
                    success: function (res) {
                        _this.loading.close();
                        if(res.code!=200){
                            _this.$message({
                                message: res.msg,
                                type: 'error'
                            });
                        }else{
                            _this.cancelRecoder();
                            _this.messageContent+='audio[' + res.result.path + ']';
                            _this.chatToUser();
                        }
                    }
                })

            },
            cancelRecoder:function(){
                this.audioDialog=false;
                if(!this.recorder){
                    return;
                }
                this.recorder.destroy();
                this.recorder=null;
                this.recoderSecond=0;
            },
            recoderFormat:function(percentage){
                return percentage+"s";
            },
            openNewWindow:function(){
                var features = "height=800px, width=960px, top=0, left=0, toolbar=no, menubar=no,scrollbars=no,resizable=no, location=no, status=no";  //设置新窗口的特性
                var me = window.open(location.href, "newW", features);
            },
            //超时关闭
            checkTimeout:function(){
                var _this=this;
                this.timeoutTimer=setInterval(function(){
                    if (Date.now() - _this.currentActiveTime >= _this.timeoutLongTime) {
                        if(_this.VisitorCommentBtn!="true"){
                            _this.comment=true;
                        }
                        console.log("长时间无操作");
                        if(_this.socket!=null){
                            _this.reconnectDialog=true;
                            _this.showTitle(KEFU_LANG[LANG]['autoclosemes']);
                            _this.socket.close();
                            _this.socket=null;
                        }
                    }
                },55000);
            },
            closeTimeoutTimer:function(){
                clearInterval(this.timeoutTimer);
            },
            cleanAllTimeout:function(){
                for(var i in this.allTimeouter){
                    clearTimeout(this.allTimeouter[i]);
                }
            },
            loadMoreMessages:function(){
                var _this=this;
                var pagesize=5;
                // if(this.currentPage>1){
                //     this.replys=[];
                // }
                if(_this.loadMoreDisable){
                    return;
                }
                var moreMessage=KEFU_LANG[LANG]['moremessage'];
                this.flyLang.moremessage=this.flyLang.loading;
                this.loadMoreDisable=true;
                var hasUnread=false;
                this.sendAjax("/2/messages_page","get",{pagesize:pagesize,ent_id:ENT_ID,page:this.currentPage,visitor_id:_this.visitor.visitor_id},function(result){
                    var len=result.list.length;
                    if(result.list.length!=0){
                        if(len<pagesize){
                            _this.showLoadMore=false;
                        }else{
                            _this.showLoadMore=true;
                        }

                        let msgList=result.list;
                        for(var i=0;i<msgList.length;i++) {
                            let visitorMes = msgList[i];
                            let content = {}
                            if (visitorMes["mes_type"] == "kefu") {
                                content.is_kefu = false;
                                content.content = replaceSpecialTag(visitorMes["content"]);
                            } else {
                                content.is_kefu = true;
                                content.content = replaceContent(visitorMes["content"]);
                            }
                            if (visitorMes["read_status"] == "read") {
                                content.read_status = KEFU_LANG[LANG].read;
                            } else {
                                content.read_status = KEFU_LANG[LANG].unread;
                                if(i==0){
                                    hasUnread=true;
                                    _this.haveUnreadMessage=true;
                                }
                            }
                            content.avator = visitorMes["avator"];
                            content.name = visitorMes["name"];
                            content.msg_id = visitorMes["msg_id"];
                            content.time = shortTime(visitorMes["time"]);
                            _this.msgList.unshift(content);
                            //_this.scrollBottom();
                        }
                    }else{
                        _this.showLoadMore=false;
                    }
                    if(_this.currentPage==1){
                        _this.scrollBottom();

                        //_this.getAutoReply();
                    }

                    _this.currentPage++;
                    _this.flyLang.moremessage=moreMessage;
                    _this.loadMoreDisable=false;
                });
            },
            //展示微信公众号带参二维码
            showWechatTip:function(){
                var _this=this;
                if(this.VisitorWechatQrcodeUrl==""||this.scanWechatQrcode!="true"){
                    return;
                }
                if(this.visitor.visitor_id.substr(0,2)=='wx'){
                    this.showTitle("微信访客用户已登录");
                    return;
                }
                var msg={};
                msg.avator = _this.noticeAvatar;
                msg.name = _this.noticeName;
                msg.show_time = true;
                msg.time = _this.getNowDate();


                var child = '<div class="wechatTip">';
                child += '<img style="width:100px; margin:6px;" src="'+this.VisitorWechatQrcodeUrl+'?visitor_id=' + this.visitor.visitor_id + '&ent_id='+ENT_ID+'">';
                child += '扫描或长按左侧二维码关注公众号。<br>可防止更换浏览器丢失消息、收不到回复。<br>并可接收回复通知</div>';
                msg.content=child;
                _this.msgList.push(msg);
            },
            sendComment:function(tagName){
                var _this=this;
                if(!_this.commentScore){
                    this.$message({
                        message: _this.flyLang.invalidParam,
                        type: 'error'
                    });
                    return;
                }
                this.sendAjax("/2/comment","post",{
                    comment_score:_this.commentScore,
                    comment_content:_this.commentContent,
                    kefu_name:this.visitor.to_id,
                    ent_id:ENT_ID,
                    visitor_id:_this.visitor.visitor_id},function(result){});
            },
            //格式化时间
            formatTime:function(time) {
                // var timeDate=new Date(time);
                // var timeStamp = Math.round(timeDate.getTime()/1000);
                // var nowTime=Math.round(new Date(new Date().toLocaleDateString()).getTime()/1000);
                // var timeDiff=timeStamp-nowTime;
                // if(timeDiff>=0){
                //     return dateFormat("H:M:S",timeDate);
                //     //return beautifyTime(timeStamp,LANG);
                // }else{
                //     return dateFormat("Y-m-d H:M:S",timeDate);
                // }
                return time;
            },
            getVersion:function(){
                if(IS_TRY=="false"){
                    return;
                }
                this.$alert('当前为试用版本,请点击底部链接获取授权', '警告!', {
                    confirmButtonText: '确定',
                });
            },
            selectLang:function(lang){
                var url=changeURLPar(document.URL,"lang",lang);
                document.location.href=url;
            },
            //focus事件处理
            focusHandle(){
                clearFlashTitle();
                window.location.reload();
            },
            visitorPageHeight(){
                //$("#chatVisitorPage").css("height","calc(100% - 121px)");
                if(isWeiXin()){
                    $("body").css("height","100vh");
                }else{
                    $("body").css("height",document.documentElement.clientHeight+"px");
                }
                //document.getElementById('chatVisitorPage').style.height = (document.documentElement.clientHeight - 71) + 'px';
            },
            checkDomainAuth(){
                return;
                var _this=this;
                $.get("/other/domainAuth",{},function(data){
                    if(data.code=="201"){
                        _this.$alert( KEFU_LANG[LANG]['authLimit'],'', {
                            callback: function(){
                                window.location.reload();
                            }
                        });
                    }
                });
            },
            initCallingDialog(){
                this.canvasElement=$('#audioCanvas')[0];
                this.videoElement=$('#chatRtc')[0];
                this.talkPeer();
            },
            //loading关闭
            loadingTimerTimeoutClose(){
                var _this=this;
                if(this.loadingTimer){
                    clearTimeout(this.loadingTimer);
                    this.loadingTimer=null;
                }
                this.loadingTimer=setTimeout(function(){
                    _this.loading.close();
                    _this.callClear();
                }, 30000);
            },
            callClear() {
                var _this=this;
                _this.isCalling=false;
                if(_this.loading){
                    _this.loading.close();
                }
                if(_this.call!=null){
                    _this.call.close();
                }
                if(_this.localStream){
                    var tracks=_this.localStream.getTracks();
                    for(var i=0;i<tracks.length;i++){
                        tracks[i].stop();
                    }
                    _this.localStream=null;
                }
            }
        },
        mounted:function() {
            var _this=this;
            document.addEventListener('paste', this.onPasteUpload);
            document.addEventListener('scroll',this.textareaBlur);
            window.addEventListener('message',function(e){
                var msg=e.data;
                if(msg.module&&msg.module=="locationPicker"){
                    _this.qqMap=false;
                    console.log('location', msg);
                    var address={
                        "title":msg.poiaddress,
                        "price":msg.poiname,
                        "img":"/static/images/qqmap.png",
                        "url":"https://apis.map.qq.com/tools/poimarker?type=0&marker=coord:"+msg.latlng.lat+","+msg.latlng.lng+"&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77&referer=myapp"
                    };
                    _this.messageContent="product["+JSON.stringify(address)+"]";
                    _this.chatToUser();
                }
                if(msg.type=="inputing_message"){
                    _this.sendInputingStrNow(msg.content);
                }
                if(msg.type=="send_message"){
                    _this.messageContent=msg.content;
                    _this.chatToUser();
                }
            });
            //监听页面关闭
            window.onbeforeunload = function(e) {
                _this.callClose();
            };
        },
        created: function () {
            this.init();
            this.getUserInfo();
            this.checkDomainAuth();
            //加载历史记录
            //this.msgList=this.getHistory();
            //滚动底部
            //this.scrollBottom();
            //获取欢迎
            //this.initPeerjs();

            //this.getVersion();
        }
    })

</script>
</html>
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-11-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 访客弹窗入口界面
  • 访客端弹窗界面
  •  访客端直接打开的界面
  •  客服端界面
相关产品与服务
腾讯企点客服
腾讯企点客服(Tencent QiDian Customer Service)是为销售和客服提供多渠道商机转化与客户服务的智能客服平台。基于腾讯云的即时通讯、音视频、人工智能、大数据、云呼叫中心等技术,以个性化服务和精准客户洞察撬动销售转化与复购增购。企点客服全面覆盖了从销售到服务的全链路业务场景,帮助企业构建一体化的客户运营体系,极大提升了企业获客、待客、留客的效率。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档