<template>
    <div class="coust-wx-chart-wrtap">
        <TopHeader :custom-title="toInfo.realname">
			<!-- 返回按钮 -->
			<i slot="backBtn" class="iconfont icon-fanhui"></i>
		</TopHeader>
        <div class="hint">
            <p>提示:长按对话框中的聊天信息,可翻译成英文</p>
            <p>Tip: long press the chat message in the dialog box, which can be translated into English</p>
        </div>
        <div class="wx-contont" :class="faceShow?'padd-340':(cameraShow?'padd-300':'')" ref="box" id="data-list-content" @click="clickEvent()">
            <ul class="w-info-" v-show="charList.length>0">
                <div>
                    <div class="look-more" v-show="isMore">查看更多</div>
                    <div class="char-info" v-for="(info,key) in charList" :key="key">
                        <p class="wx-c-timer">{{info.add_time |formatDate}}</p>
                        <li :class="info.sender==1 ? 'right-info-wrap':'lef-info-wrap'">
                            <img v-if="info.sender==2" class="-info-icon" :src="toInfo.avatar" />
                            <img v-if="info.msg_type==2" class="up-img" :src="info.content" @click="showBigPic(info.content)"/>
                            <span v-else="" class="-info-msg" @touchstart.prevent="touchin(1,key,info.content)">{{info.content}}</span>
                            <img  v-if="info.sender==1" class="-info-icon" :src="from_info.avatar" />
                        </li>
                        <div class="tranfrom-msg" :class="info.sender==1 ? 'ri-tranfrom':'lef-tranfrom'" v-if="info.isEnglish"> {{info.english}}</div>
                    </div>
                </div>
            </ul>
            <ul class="w-info-" v-show="list.length>0">
                <div>
                    <div class="char-info" v-for="(info,key) in list" :key="key">
                        <p class="wx-c-timer">{{info.add_time |formatDate}}</p>
                        <li :class="info.sender==1 ? 'right-info-wrap':'lef-info-wrap'">
                            <img v-if="info.sender==2" class="-info-icon" :src="toInfo.avatar" />
                            <img v-if="info.say_type==2" class="up-img" :src="info.content" @click="showBigPic(info.content)"/>
                            <span v-else="" class="-info-msg" @touchstart.prevent="touchin(2,key,info.content)">{{info.content}}</span>
                            <img  v-if="info.sender==1" class="-info-icon" :src="from_info.avatar" />
                        </li>
                        <div class="tranfrom-msg" :class="info.sender==1 ? 'ri-tranfrom':'lef-tranfrom'" v-if="info.isEnglish"> {{info.english}}</div>
                    </div>
                </div>
            </ul>
        </div>
        <!-- footer start -->
        <div class="footer-wrap">
            <div class="foot-box">
                <div class="foot-box-input">
                    <input class="-box-input1" type="text" placeholder="请输入您要表达的内容" v-model="textConent" @focus="getFocus"/>
                    <div class="icon-wrap">
                    <span class="icon-cont">
                        <i class="iconfont icon-jia3" v-show="!cameraShow" @click="showCamera()"></i>
                    </span>
                    <span class="icon-cont">
                        <i class="iconfont icon-xiaolian " v-show="!faceShow" @click="sendMemes()"></i>
                        <i class="iconfont icon-jianpan" v-show="faceShow" @click="sendMemes()"></i>
                    </span>
                    </div>
                </div>
                <input  type="button" class="foot-btn" value="发送" @click="sendMessage()" />
            </div>

            <div class="camera-wrap info_window" v-show="cameraShow">
                <van-uploader  multiple :after-read="afterRead"/>
            </div>
            <!-- 表情包开始 -->
            <div class="info_window" v-show="faceShow">     
	            <div class="im_face">
	                <div class="scene_scroll">
		                <div class="scene">
                            <li class="face" v-for="(item,index) in faceList" :key="index" @click="getBrow(index)">{{item}}</li>
		                </div>
		             </div>
	            </div>
            </div>
            <!-- 表情结束 -->
        </div>
        <!-- footer end -->
    </div>
</template>
<script>
import TopHeader from "@/pages/common/header/TopHeader";
import { ImagePreview } from 'vant';
// 导入JSON格式的表情库
const appData = require("@/assets/emojis.json");

export default {
    components:{
        TopHeader
    },
    data(){
       return{
            timer:'',
            list:[],                //对话信息
            charList:[],            //聊天记录
            doctorInfo:{},
            textConent: "",         //存放输入的内容
            getBrowString:"",      //存放表情
            faceList: [],           //表情库
            fsConent:"",
            from_info:{},
            toInfo:{},
            fileList:[],            //图片数组 
            fileImg:'',             //转换后的图片
            isMore:false,           //查看更多
            faceShow:false,         //表情包
            cameraShow:false,        //上传图片
            Loop:0                  //手指长按
        }
    },
    created(){
        this.getDotaInfo()
        for (let i in appData) {
            this.faceList.push(appData[i].char);
        }
    },
    mounted(){
        var userMessag =JSON.parse(localStorage.getItem('userMessage'))
        if(userMessag !=null || 'undefined' !=typeof(userMessag)){
            this.userInfo=userMessag
        }  
    },
    methods:{
        showBigPic(img){
            ImagePreview([img]);
        },
        touchin(type,index,msg){
            var that=this;
            this.Loop = setTimeout(function() {
            that.Loop = 0;
            msg =that.$commons.removeSpace(msg)
            that.$axios.post('doctor/youdao_transLate',{
                'word':msg
            }).then((res)=>{
                    var info =res.data
                    if(res.status==200){
                        if(type==1){
                            if(that.charList[index].msg_type==1){
                                that.$set(that.charList[index],'english',info)
                                that.$set(that.charList[index],'isEnglish',true)
                            }
                            else{
                                that.$toast("只能翻译文字哦")
                            }
                        }else{
                            if(that.list[index].say_type==1){
                                that.$set(that.list[index],'english',info)
                                that.$set(that.list[index],'isEnglish',true)
                            }
                            else{
                                that.$toast("只能翻译文字哦")
                            }
                        }
                    }
                })
            }, 700);
            that.$forceUpdate()
            // that.scrollToBottom()
            return false;
        },
        getFocus(){
            this.textConent =''
            this.faceShow=false
            this.cameraShow=false 
        },
        clickEvent(){
            this.faceShow=false
            this.cameraShow=false
        },
        showCamera(){
            this.textConent =''
            this.faceShow =false
            this.cameraShow =!this.cameraShow
            this.scrollToBottom()
        },
        afterRead(file){
            var that =this
            that.fileList=[]
            if(/\/(?:jpeg|png)/i.test(file.file.type) && file.file.size > 1500000) {
                let canvas =  document.createElement('canvas')        // 创建Canvas对象(画布)
                let context = canvas.getContext('2d') 
                let img = new Image()                   // 创建新的图片对象 
                // 指定图片的DataURL(图片的base64编码数据)
                img.src = file.content
                img.onload =() =>{
                    canvas.width =400
                    canvas.height =300
                    context.drawImage(img,0,0,400,300)
                    file.content =canvas.toDataURL(file.file.type,0.92)
                    that.$axios.post('doctor/create_img',{
                        token:that.$store.getters.optuser.Authorization,
                        image:file.content
                    }).then((res)=>{
                        that.fileList.push(res.data)
                        that.wxChart(false,true) 
                    })
                } 
            }else{
                that.$axios.post('doctor/create_img',{
                    token:that.$store.getters.optuser.Authorization,
                    image:file.content
                }).then((res)=>{
                    // console.log(res.data)
                    that.fileList.push(res.data)
                    that.wxChart(false,true) 
                })
            }
        },
        scrollToBottom () {
            this.$nextTick(() => {
                setTimeout(() => {
                var scrollTop = this.$el.querySelector('.wx-contont')
                scrollTop.scrollTop = scrollTop.scrollHeight
                }, 13)
            })
        },
        getChart(){
            let that=this
            that.$axios.post('doctor/load',{
                token:that.$store.getters.optuser.Authorization,
                toid:that.$route.query.id
            }).then((res)=>{
                var list = res.data
                if(list.status===200){
                    if(list.data.length>10){
                        that.isMore =true
                    }
                    for(var i in list.data){
                        if(list.data[i].msg_type==5){
                            list.data[i].content =that.getEmojis(list.data[i].content)
                        }
                        list.data[i].isEnglish=false
                        list.data[i].english=''
                    }
                    that.charList =list.data;
                    that.scrollToBottom()
                }
                else if(list.status == 999){
                    that.$store.commit('del_token'); //清除token;
                    setTimeout(()=>{
                        that.$router.push('/Login')
                    },1000)
                }
                else{
                    that.$toast(list.msg)
                }
            })
        },
        getEmojis(data){
            data =data.split(',')
            var cont =''
            for(var i in data){
                for(var j in this.faceList){
                    if(j == data[i]){
                        cont +=this.faceList[j]
                    }
                }
            }
            return cont
        },
        getBrow(index) {
            for (let i in this.faceList) {
                if (index == i) {
                this.getBrowString += ','+index
                this.fsConent +=this.faceList[index]
                this.textConent = this.fsConent
                }
            }
        },
        getDotaInfo(){
            let that=this
            that.$axios.post('doctor/get_userinfo',{
                toid:this.$route.query.id,
                sender:1,
                token:this.$store.getters.optuser.Authorization
            }).then((res)=>{
                var list = res.data
                if(list.status===200){
                    that.doctorInfo =list.data;
                    that.from_info =list.data.from_info
                    that.toInfo =list.data.to_info
                    that.getChart()
                    that.wxChart(true)
                }
                else if(list.status == 999){
                    that.$store.commit('del_token'); //清除token;
                    setTimeout(()=>{
                        that.$router.push('/Login')
                    },1000)
                }
                else{
                    that.$toast(list.msg)
                }
            })
        },
        onDivInput($event){
            this.inpumsg2 =$event.data
        },
        sendMessage(){
            var that =this
            if (this.textConent == "") return that.$toast("请输入内容");            // 清空input数据
            this.wxChart(false,false)
        },
        sendMemes(){
            this.textConent =''
            this.fsConent=""
            this.cameraShow=false
            this.faceShow = !this.faceShow;
            this.scrollToBottom()
        },
        wxChart(isFrist,isImg) {
            let that = this;
            var timer=''
            var timer =that.$commons.timeStemp(false,true)
            if (window.WebSocket){
                var domain='medicine_doctor.zhifengwangluo.com'
                let ws =new WebSocket("ws://"+domain+":7272")
                ws.onopen = function (e) {
                    console.log("链接服务器成功");
                    if(isFrist){     //初始化时执行
                        var login_data = '{"type":"login","client_name":"'+that.from_info.realname+'","ud_type":"1","ud_id":"'+that.from_info.id+'"}'
                    }else{
                        if(isImg){
                            var login_data = '{"type":"say","say_type":"2","to_client_name":"'+that.from_info.realname+'","content":"'+that.fileList[0].replace(/"/g, '\\"').replace(/\n/g,'\\n').replace(/\r/g, '\\r')+'","ud_type":"1","ud_id":"'+that.from_info.id+'","to_id":"'+that.$route.query.id+'"}';
                            that.list.push({add_time:timer,sender:1,say_type:2,content:that.fileList[0],isEnglish:false,english:''})
                        }else{
                            // var cont =that.textConent
                            var cont =that.$commons.removeSpace(that.textConent)
                            var say_type =1
                            if(that.getBrowString!=""){
                                cont=that.getBrowString
                                say_type =5
                            }
                            var login_data = '{"type":"say","say_type":"'+say_type+'","to_client_name":"'+that.from_info.realname+'","content":"'+cont.replace(/"/g, '\\"').replace(/\n/g,'\\n').replace(/\r/g, '\\r')+'","ud_type":"1","ud_id":"'+that.from_info.id+'","to_id":"'+that.$route.query.id+'"}';
                            that.list.push({add_time:timer,sender:1,say_type:say_type,content:cont,isEnglish:false,english:''})
                        }
                    }
                    ws.send(login_data);
                    that.textConent = ""
                    that.getBrowString=[]
                    that.fsConent = ""
                    that.faceShow = false
                    that.cameraShow =false
                };
                ws.onclose = function (e) {
                    console.log("服务器关闭")
                    that.$toast("网络出错,服务器关闭")
                };
                ws.onerror = function () {
                    console.log("服务器出错")
                    that.$toast("服务器出错,自动关闭")
                };
                ws.onmessage = function (e) {
                    console.log(e)
                    var info =JSON.parse(e.data)
                    if(info.type==="ping"){
                        ws.send('{"type":"pong"}');
                        return
                    }
                    console.log(info)
                    var cont =info.content
                    // var say_type =1
                    if(info.type=="say" && info.to_client_id !=null){
                        if(info.say_type==5){
                            cont =that.getEmojis(info.content)
                        }
                        that.list =[...that.list, {add_time:timer,sender:2,say_type:info.say_type,content:cont,isEnglish:false,english:''}]
                    }
                    
                }
            }


            
        },



        closeSendMemes(){
            this.faceShow=false
        }
    },
    filters: {
        // 日期格式化
        formatDate: function (time) {
            let date = new Date(time*1000);
            let y = date.getFullYear();

            let MM = date.getMonth() + 1;
            MM = MM < 10 ? ('0' + MM) : MM;

            let d = date.getDate();
            d = d < 10 ? ('0' + d) : d;

            let h = date.getHours();
            h = h < 10 ? ('0' + h) : h;

            let m = date.getMinutes();
            m = m < 10 ? ('0' + m) : m;

            let s = date.getSeconds();
            s = s < 10 ? ('0' + s) : s;

            return y + '-' + MM + '-' + d + ' '+h+':'+m+':'+s;
        }
    },
    watch: {
      //监听list,当有修改的时候进行div的屏幕滚动,确保能看到最新的聊天
      list: function () {
            this.scrollToBottom()
        //加setTimeout的原因:由于vue采用虚拟dom,我每次生成新的消息时获取到的div的scrollHeight的值是生成新消息之前的值,所以造成每次都是最新的那条消息被隐藏掉了
      }
    },
    
}
</script>
<style scoped lang="stylus">
    .coust-wx-chart-wrtap
        width 100%
        height 100vh
        position relative
        overflow hidden
    .hint
        background rgba(255,255,255,0.7)
        position absolute
        z-index 100
        padding 10px
        font-size 24px
        letter-spacing 2px
        box-shadow 0 0 10px #ccc
        p
            margin-bottom 10px
    .wx-contont
        width 100%
        height 100%
        position absolute
        left 0
        top 0
        padding 240px 24px 110px
        box-sizing border-box
        overflow-y auto 
        overflow-x hidden
        font-size 28px
        .look-more
            text-align center
            color #999
            line-height 44px
            margin 4px auto
            font-size 22px
        .char-info
            width 100%
            overflow hidden
        .wx-c-timer
            text-align center
            font-size 22px
            color #777
            padding 10px 0
    .padd-340
        padding-bottom 340px
    .padd-300
        padding-bottom 300px
    .lef-info-wrap,.right-info-wrap
        display flex
        width 100%
        position relative
        align-items center
        margin-bottom 22px
        .-info-icon
            width 80px
            height 80px
            border-radius 50%
            object-fit contain
            border 2px solid #7981d4
        .up-img
            width 90px
            height 90px
            margin 0 26px
            border-radius 10px
            border 2px solid #ccc
            padding 3px
        .-info-msg
            display block
            max-width 70%
            margin-left 23px
            line-height 50px
            background-color #e6e8f7
            border-radius 30px 30px 30px 0px
            padding 6px 12px
            font-size 28px
            letter-spacing 2px
            display flex
            align-items center
        .-info-msg /deep/ .icon-sty ,.-info-msg /deep/ .icon-sty
            width 40px
            height 40px
            margin 0 4px
    .tranfrom-msg
        background #fff
        border-radius 6px
        margin-bottom 10px
        display inline-block
    .lef-tranfrom
        margin-left 90px
        padding 6px 12px
    .ri-tranfrom
        margin-right 90px
        padding 6px 12px
        float right
    .right-info-wrap
        justify-content flex-end
        .-info-msg
            margin-right 23px
            background-color #777ec0
            border-radius 30px 30px 0px 30px
            color #fff
    .footer-wrap
        position absolute
        bottom 0
        left 0
        z-index 10
        width 100%
    .foot-box
        background #6771ce
        height 88px
        display flex
        align-items center
        justify-content center
        .foot-box-input
            width 570px
            height 50px
            background #fff
            position relative
            border-radius 25px
            padding 0 13px
            box-sizing border-box
            margin-right 22px
            .-box-input1
                width 490px
                height 50px
                line-height 50px
            .-box-input3
                overflow-x auto 
                overflow-y hidden
                outline none
            .-box-input3 /deep/ .icon-sty
                width 40px
                height 40px
                margin 0 2px
            .icon-wrap
                position absolute
                right 5px
                font-size 42px
                top 0
                line-height 50px
                height 50px
                font-size 0
            .iconfont
               font-size 45px
        .foot-btn
            width 113px
            height 50px
            background-color #2b337e
            border-radius 25px
            text-align center
            color #fff
    .info_window 
        // display none
        width 100%
        text-align center
        overflow hidden
        height 240px
        overflow-y auto
        overflow-x hidden
        padding-bottom 8px
        background #fff
        .scene_scroll
            width 100%
        .scene
            display flex
            flex-wrap wrap
            width 100%
            .face  
                display block
                width 70px
                height 70px
                font-size 45px
                img
                    width 100%
                    height 100%
    .camera-wrap
        height 200px
        display flex
        align-items center
        justify-content center
    .camera-wrap /deep/ .van-uploader__upload
        margin 0
</style>
<style lang="stylus">
    .van-image-preview__overlay
        background-color: rgba(0,0,0,.6);
    .van-image-preview__image 
        position: absolute
        top: 0
        right: 0
        bottom: 0
        left: 0
        width: 70%
        height: 70%
        margin: auto
        object-fit: contain
</style>

 

Logo

前往低代码交流专区

更多推荐