|
|
@@ -1,2173 +1,2177 @@
|
|
|
-<template>
|
|
|
- <div>
|
|
|
- <!-- 聊天 -->
|
|
|
- <div class="service" v-if="!knowledge">
|
|
|
- <!-- 头部信息 -->
|
|
|
- <div class="header row allAlignment item-center">
|
|
|
-
|
|
|
- <div class="row item-center" v-if="!link_success">
|
|
|
- <img class="icon" style="margin-right:.2rem;" src="@/assets/Service1.png" @click="leftShow = true">
|
|
|
- <img class="logo" :src="img_http + logo" alt="">
|
|
|
- <p>{{service_info.name}}</p>
|
|
|
- <span style="margin:5px 0 0 5px"><img src="@/assets/on_icon.png" alt=""></span>
|
|
|
- </div>
|
|
|
- <div class="row item-center" v-else>
|
|
|
- <img class="icon" style="margin-right:.2rem;" src="@/assets/Service1.png" @click="leftShow = true">
|
|
|
- <img class="logo" :src="img_http + logo" alt="">
|
|
|
- <p>{{service_info.name}}</p>
|
|
|
- <span v-if="service_on" style="margin:5px 0 0 5px"><img src="@/assets/on_icon.png" alt=""></span>
|
|
|
- <span v-if="!service_on" style="margin:5px 0 0 5px"><img src="@/assets/off_icon.png" alt=""></span>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="row">
|
|
|
- <yd-button v-if="isExit" color="#fff" bgcolor="#1d57dd" class="exit" size="mini" type="primary"
|
|
|
- @click.native="is_exit()">结束聊天
|
|
|
- </yd-button>
|
|
|
- <img class="icon-msg" v-if="( chat.length -1 ) + hisLength >= chatNum" @click="is_show_evaluate()" src="@/assets/Service2.png">
|
|
|
- <img class="icon-msg" @click="knowledge = true,flag = false" src="@/assets/leaveSwitch.png" v-if="!isExit">
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="main" id="main" @scroll="scrollMain">
|
|
|
-
|
|
|
- <!-- ********************************************************** -->
|
|
|
- <!-- 机器人聊天板块 -->
|
|
|
- <div v-if="!link_success">
|
|
|
- <!-- 系统欢迎语 -->
|
|
|
- <div v-if="welcome.length > 0" v-for="(item,i) in welcome" :key="'w'+i">
|
|
|
- <div class="row allAlignment" style="margin-top:.3rem;">
|
|
|
- <div class="HeadPortrait row center">
|
|
|
- <img :src="require('@/assets/headAdvent.png')">
|
|
|
- </div>
|
|
|
- <div class="messageWindow dialogueA col-w">
|
|
|
- <div class="customerService left" v-html="item"></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 系统消息下拉选择 -->
|
|
|
- <div class="artificial" v-if="problem.length > 0 && welcome.length > 0">
|
|
|
- <div class="row item-center allAlignment" style="height:.75rem;border-bottom:.01rem solid #EEE;"
|
|
|
- v-for="(item,index) in problem" :key="index" @click="pushMessage(item.robot_content)">
|
|
|
- <span>{{item.robot_name}}</span>
|
|
|
- <img style="width:.3rem;height:.3rem;" src="@/assets/addright.png">
|
|
|
- </div>
|
|
|
- <div class="row item-center" style="height:.72rem;">
|
|
|
- <p>以上问题都不是</p>
|
|
|
- <div style="color:#5EA0F7;padding-left:.1rem;" @click="connectionService">转人工客服</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 和机器人会话 -->
|
|
|
- <div v-for="(item,i) in robot" :key="'r'+i">
|
|
|
- <!-- 和机器人会话互动 -->
|
|
|
- <div v-if="item.type == 'error'" class="row allAlignment"
|
|
|
- style="margin-top:.3rem;">
|
|
|
- <div class="HeadPortrait row center">
|
|
|
- <img v-if="item.type == 'error'" :src="require('@/assets/headAdvent.png')">
|
|
|
- </div>
|
|
|
- <div class="messageWindow dialogueA col-w">
|
|
|
- <!-- <div v-if="item.type == '1001'" class="customerService left"
|
|
|
- v-html="item.content.text"></div> -->
|
|
|
- <!-- <div v-if="item.type == 'user'" class="user right imgSrc">
|
|
|
- <yd-lightbox v-if="item.content.img" style="display:inline-block"
|
|
|
- class="row rightAlignment box-img">
|
|
|
- <yd-lightbox-img :src=" img_http + item.content.img"></yd-lightbox-img>
|
|
|
- </yd-lightbox> -->
|
|
|
- <div v-if="item.type == 'error'" class="customerService left">{{item.content.text}}
|
|
|
- <div style="color:#5EA0F7;padding-left:.1rem;cursor:pointer;" @click="connectionService">转人工客服</div>
|
|
|
- </div>
|
|
|
- <!-- </div> -->
|
|
|
- </div>
|
|
|
- <div class="HeadPortrait row center">
|
|
|
- <img v-if="item.type == 'user'"
|
|
|
- :src="require('@/assets/timg.jpg') ">
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
-
|
|
|
- <!-- 和机器人会话互动 -->
|
|
|
- <div v-if="item.type == 'service' || item.type == 'user'" class="row allAlignment"
|
|
|
- style="margin-top:.3rem;">
|
|
|
- <div class="HeadPortrait row center">
|
|
|
- <img v-if="item.type == 'service'" :src="require('@/assets/headAdvent.png')">
|
|
|
- </div>
|
|
|
- <div class="messageWindow dialogueA col-w"
|
|
|
- :style="item.type == 'user'?'text-align: right;':''">
|
|
|
- <div v-if="item.type == 'service'" class="customerService left"
|
|
|
- v-html="item.content.text"></div>
|
|
|
- <div v-if="item.type == 'user'" class="user right imgSrc">
|
|
|
- <yd-lightbox v-if="item.content.img" style="display:inline-block"
|
|
|
- class="row rightAlignment box-img">
|
|
|
- <yd-lightbox-img :src=" img_http + item.content.img"></yd-lightbox-img>
|
|
|
- </yd-lightbox>
|
|
|
- <div v-else v-html="item.content"></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="HeadPortrait row center">
|
|
|
- <img v-if="item.type == 'user'"
|
|
|
- :src="require('@/assets/timg.jpg') ">
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 转人工分组 -->
|
|
|
- <div class="artificial" v-if="item.type == 'artificial_service' ">
|
|
|
- <div @click="turnArtificial(items.id)" v-for="(items,indexs) in item.content"
|
|
|
- :key="'r'+indexs" class="row item-center allAlignment"
|
|
|
- style="height:.75rem;border-bottom:.01rem solid #EEE;">
|
|
|
- <p>
|
|
|
- 人工客服:
|
|
|
- <span style="color:#5EA0F7;padding-left:.1rem;">{{items.name}}</span>
|
|
|
- </p>
|
|
|
- <img style="width:.3rem;height:.3rem;" src="@/assets/addright.png">
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- ********************************************************** -->
|
|
|
- <!-- 人工会话模版 -->
|
|
|
- <div v-if="link_success">
|
|
|
- <!--历史消息-->
|
|
|
- <div v-if="showHistory" v-for="(item, index) in hisSviceChat" :key="'h'+index">
|
|
|
- <!-- 客服信息 -->
|
|
|
- <div v-if="item.from_id.startsWith('KF')">
|
|
|
- <div style="width: 100%;text-align: center;">
|
|
|
- <span v-if="item.time_line">{{item.time_line}}</span>
|
|
|
- </div>
|
|
|
- <div class="row allAlignment" style="margin-top:.3rem;margin-top: 0.3rem;">
|
|
|
- <div class="HeadPortrait row center">
|
|
|
- <img v-if="service_info.avatar == '' " :src="avatar_imgs">
|
|
|
- <img v-if="service_info.avatar != ''"
|
|
|
- :src="img_http + service_info.avatar ? img_http + service_info.avatar : require('@/assets/user2.png')">
|
|
|
- </div>
|
|
|
- <div class="messageWindow dialogueA col-w">
|
|
|
- <div class="customerService left imgSrc">
|
|
|
- <yd-lightbox v-if="item.content.img" style="display:inline-block"
|
|
|
- class="row rightAlignment">
|
|
|
- <yd-lightbox-img :src=" img_http + item.content.img"></yd-lightbox-img>
|
|
|
- </yd-lightbox>
|
|
|
- <div v-html="item.content.text" v-else></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="HeadPortrait row center">
|
|
|
-
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 用户信息 -->
|
|
|
- <div v-else>
|
|
|
- <div style="width: 100%;text-align: center;margin-top: 0.3rem;">
|
|
|
- <span v-if="item.time_line">{{item.time_line}}</span>
|
|
|
- </div>
|
|
|
- <div class="row allAlignment" style="margin-top:.3rem;">
|
|
|
- <div class="HeadPortrait row center">
|
|
|
-
|
|
|
- </div>
|
|
|
- <div class="messageWindow dialogueA col-w row rightAlignment" >
|
|
|
- <div class="user right imgSrc ">
|
|
|
- <yd-lightbox v-if="item.content.img" style="display:inline-block" class="row rightAlignment">
|
|
|
- <yd-lightbox-img :src="img_http+item.content.img"></yd-lightbox-img>
|
|
|
- </yd-lightbox>
|
|
|
- <div v-html="item.content.text" v-else></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="HeadPortrait row center">
|
|
|
- <img :src="require('@/assets/timg.jpg') ">
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div v-for="(item,index) in chat" :key="index">
|
|
|
-
|
|
|
- <!-- 展示历史消息 -->
|
|
|
- <div class="promptBox" v-if="item.type == 'historyMsg'">
|
|
|
- <div class="prompt help">
|
|
|
- <span>{{historyMsgtext}}</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 客服会话 -->
|
|
|
- <div v-if="item.type == 'service'">
|
|
|
- <div style="width: 100%;text-align: center;margin-top: 0.3rem;">
|
|
|
- <span v-if="item.time ">{{item.time}}</span>
|
|
|
- </div>
|
|
|
- <div class="row allAlignment" style="margin-top:.3rem;">
|
|
|
- <div class="HeadPortrait row center">
|
|
|
- <img id="123" v-if="service_info.avatar == '' " :src="avatar_imgs">
|
|
|
- <img id="321" v-if="service_info.avatar != '' "
|
|
|
- :src="img_http + service_info.avatar ? img_http + service_info.avatar : img_http + service_info.avatar">
|
|
|
- </div>
|
|
|
- <div class="messageWindow dialogueA col-w ">
|
|
|
- <div class="customerService left imgSrc">
|
|
|
- <yd-lightbox v-if="item.content.img" style="display:inline-block"
|
|
|
- class="row rightAlignment">
|
|
|
- <yd-lightbox-img :src="img_http + item.content.img"></yd-lightbox-img>
|
|
|
- </yd-lightbox>
|
|
|
- <div v-html="item.content.text" v-else></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="HeadPortrait row center">
|
|
|
-
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 用户会话 -->
|
|
|
- <div v-if="item.type == 'user'">
|
|
|
- <div style="width: 100%;text-align: center;margin-top: 0.3rem;">
|
|
|
- <span v-if="item.time">{{item.time}}</span>
|
|
|
- </div>
|
|
|
- <div class="row allAlignment" style="margin-top:.3rem;">
|
|
|
- <div class="HeadPortrait row center">
|
|
|
-
|
|
|
- </div>
|
|
|
- <div class="messageWindow dialogueA col-w row rightAlignment" >
|
|
|
- <div class="user right imgSrc ">
|
|
|
- <yd-lightbox v-if="item.content.img" style="display:inline-block"
|
|
|
- class="row rightAlignment">
|
|
|
- <yd-lightbox-img :src="img_http+item.content.img"></yd-lightbox-img>
|
|
|
- </yd-lightbox>
|
|
|
- <span v-html="item.content.text" v-else>{{item.content.text}}</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="HeadPortrait row center">
|
|
|
- <img v-if="item.type == 'user'"
|
|
|
- :src="require('@/assets/timg.jpg') ">
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 常规系统消息评价 -->
|
|
|
- <div class="row center " v-if="item.type== 'system' ">
|
|
|
- <div class="column item-center "
|
|
|
- style="margin: 0.3rem 0; background: #fff; width:100% ;padding: 0.1rem 0;"
|
|
|
- v-if="item.content.state =='getEvaluate' && !haveEvaluation ">
|
|
|
- <p class="row center wrap">{{item.content.text}}</p>
|
|
|
- <button class="evaluateBtn" style="margin-top:.2rem;" @click="is_show_evaluate()">评价
|
|
|
- </button>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="column item-center"
|
|
|
- style="margin: 0.3rem 0; background: #fff; width:100% ;padding: 0.1rem 0.5rem;"
|
|
|
- v-if="item.content.state == 'closeInform' ">
|
|
|
- <p class="row center wrap">{{item.content.text}}</p>
|
|
|
- </div>
|
|
|
-
|
|
|
-
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div v-if="Chrome_height" style="height:40px">
|
|
|
-
|
|
|
- </div>
|
|
|
-
|
|
|
- <div v-if="Safari_height" style="height:90px">
|
|
|
-
|
|
|
- </div>
|
|
|
-
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 底部弹窗评价 -->
|
|
|
- <yd-popup v-model="bottomShow" position="bottom" height="6.5rem" :masker-opacity=".2">
|
|
|
- <div class="row rightAlignment" style="padding-top:.2rem;padding-right:.2rem;">
|
|
|
- <img @click.stop="bottomShow = false, evaluateState = 100" style="width: 0.32rem;height: 0.32rem;"
|
|
|
- src="@/assets/Service5.png">
|
|
|
- </div>
|
|
|
- <div style="color:#666;text-align: center;font-size:.28rem;">感谢您的咨询,请对我们的服务做出评价</div>
|
|
|
- <div style="height:2.3rem;" class="row allAlignment evaluatebtn">
|
|
|
- <div style="width:33%;height:100%;">
|
|
|
- <div class="row wrap center" @click="evaluateClick(1)">
|
|
|
- <img style="width:.66rem;height:.66rem;"
|
|
|
- :src="evaluateState =='1'?require('@/assets/evaluate1a.png'):require('@/assets/evaluate1.png')">
|
|
|
- <p>满意</p>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div style="width:33%;height:100%;" @click="evaluateClick(2)">
|
|
|
- <div class="row wrap center">
|
|
|
- <img style="width:.66rem;height:.66rem;"
|
|
|
- :src="evaluateState =='2'?require('@/assets/evaluate2a.png'):require('@/assets/evaluate2.png')">
|
|
|
- <p>一般</p>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div style="width:33%;height:100%;" @click="evaluateClick(3)">
|
|
|
- <div class="row wrap center">
|
|
|
- <img style="width:.66rem;height:.66rem;"
|
|
|
- :src="evaluateState =='3'?require('@/assets/evaluate3a.png'):require('@/assets/evaluate3.png')">
|
|
|
- <p>不满意</p>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- <div class="evaluateBox">
|
|
|
- <textarea placeholder="评价备注" v-model="evalArea"></textarea>
|
|
|
- </div> -->
|
|
|
- <div class="row center sub" @click="evaluateEsc">确定</div>
|
|
|
- </yd-popup>
|
|
|
-
|
|
|
- <!-- 左侧弹窗客服信息 -->
|
|
|
- <yd-popup v-model="leftShow" position="left" width="4.8rem" :masker-opacity=".2">
|
|
|
- <div class="leftHader row item-center">
|
|
|
- <img @click="leftShow = false" class="icon" src="@/assets/Service4.png">
|
|
|
- <img class="logo" :src="img_http + logo" alt="">
|
|
|
- <p style="color:#FFF;font-size:.34rem;">{{service_info.name}}</p>
|
|
|
-
|
|
|
-
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- <div class="leftMain-top row">
|
|
|
- <div>
|
|
|
- <p>
|
|
|
- <!-- 客服名字 -->
|
|
|
- <span>姓名:</span>
|
|
|
- {{service_info.name}}
|
|
|
- </p>
|
|
|
- <p>
|
|
|
- <!-- 客服工号 -->
|
|
|
- <span>工号:</span>
|
|
|
- {{service_info.job_name}}
|
|
|
- </p>
|
|
|
- <p>
|
|
|
- <!-- 客服性别 -->
|
|
|
- <span>性别:</span>
|
|
|
- {{service_info.gender == "0" ? "保密" :service_info.gender == 1? '男' :'女' }}
|
|
|
- </p>
|
|
|
- <p>
|
|
|
- <!-- 客服职务 -->
|
|
|
- <span>职务:</span>
|
|
|
- {{service_info.job_name}}
|
|
|
- </p>
|
|
|
- </div>
|
|
|
- <div class="row center">
|
|
|
- <img style="width:1.8rem;height:1.8rem;" v-if="!trueImg" :src="avatar_imgs">
|
|
|
- <!-- {{service_info.avatar}} -->
|
|
|
- <img style="width:1.8rem;height:1.8rem;" v-if="trueImg" :src="img_http +service_info.avatar">
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="leftMain-chenter"
|
|
|
- style="padding:0 .3rem;margin-top:.3rem;padding-bottom:.6rem;border-bottom:.01rem solid #ddd;"
|
|
|
- >
|
|
|
- <!-- 客服个性签名 -->
|
|
|
- <span>个性签名:</span>
|
|
|
- {{service_info.signature}}
|
|
|
- </div>
|
|
|
- <!-- 广告图 -->
|
|
|
- <div class="leftMain-bottom row center" style="padding:0 .3rem;margin-top:.6rem;">
|
|
|
- <a :href="'https://'+advertisement.advertisement_url" target="_blank" rel="noopener noreferrer">
|
|
|
- <img style="width:4.2rem;height:7rem;" :src="img_http+advertisement.advertisement_img">
|
|
|
- </a>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </yd-popup>
|
|
|
- <!-- 底部输入框 -->
|
|
|
- <div class="footer row wrap" id='input_box'>
|
|
|
- <!-- @keydown="inputNumFun()" -->
|
|
|
- <textarea
|
|
|
- id="textarea"
|
|
|
- v-model.trim="text_info"
|
|
|
- placeholder="请输入你的问题:"
|
|
|
- maxlength="450"
|
|
|
- @keyup ='keyup_maxlength()'
|
|
|
- @focus="keyup_maxlength()"
|
|
|
- :style="{height:iboxheight}"
|
|
|
- >
|
|
|
- </textarea>
|
|
|
- <div class="send row item-center" style="border-bottom:.01rem solid #ddd;">
|
|
|
- <img
|
|
|
- :src="meme?require('@/assets/faceActive.png'):require('@/assets/face.png')"
|
|
|
- @click="faceClick"
|
|
|
- style="width:.48rem;height:.48rem"
|
|
|
- >
|
|
|
- <input type="file" id="file" @change="uploadIMG" accept="image/jpeg,image/jpg,image/png,image/svg"
|
|
|
- style="display:none">
|
|
|
- <label for="file">
|
|
|
- <img src="@/assets/imge.png" style="width:.46rem;height:.42rem">
|
|
|
- </label>
|
|
|
- <div
|
|
|
- @click="send()"
|
|
|
- style="color:#ccc;border:.02rem solid #ddd;width:1rem;height:.66rem;border-radius:.1rem;"
|
|
|
- :style="text_info.length>0?'background:#5EA0F7;color:#fff;':''"
|
|
|
- class="row center"
|
|
|
- >发送
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 表情包 -->
|
|
|
- <div v-show="meme" class="memeBox">
|
|
|
- <yd-slider autoplay="0" :loop="false">
|
|
|
- <yd-slider-item>
|
|
|
- <div>
|
|
|
- <ul style="width:100%;padding-bottom:.3rem;" class="row average wrap">
|
|
|
- <li v-for="(item,index) in frceArr" :key="index" v-show="index<15">
|
|
|
- <img
|
|
|
- class="memeImg"
|
|
|
- :src="require(`@/assets/${index}.gif`)"
|
|
|
- @click="memeImg(index)"
|
|
|
- >
|
|
|
- </li>
|
|
|
- </ul>
|
|
|
- </div>
|
|
|
- </yd-slider-item>
|
|
|
- <yd-slider-item>
|
|
|
- <div>
|
|
|
- <ul style="width:100%;padding-bottom:.3rem;" class="row average wrap">
|
|
|
- <li v-for="(item,index) in frceArr" :key="index" v-show="index>15&&index<=30">
|
|
|
- <img
|
|
|
- class="memeImg"
|
|
|
- :src="require(`@/assets/${index}.gif`)"
|
|
|
- @click="memeImg(index)"
|
|
|
- >
|
|
|
- </li>
|
|
|
- </ul>
|
|
|
- </div>
|
|
|
- </yd-slider-item>
|
|
|
- <yd-slider-item>
|
|
|
- <div>
|
|
|
- <ul style="width:100%;padding-bottom:.3rem;" class="row average wrap">
|
|
|
- <li v-for="(item,index) in frceArr" :key="index" v-show="index>30&&index<=45">
|
|
|
- <img
|
|
|
- class="memeImg"
|
|
|
- :src="require(`@/assets/${index}.gif`)"
|
|
|
- @click="memeImg(index)"
|
|
|
- >
|
|
|
- </li>
|
|
|
- </ul>
|
|
|
- </div>
|
|
|
- </yd-slider-item>
|
|
|
- <yd-slider-item>
|
|
|
- <div>
|
|
|
- <ul style="width:100%;padding-bottom:.3rem;" class="row average wrap">
|
|
|
- <li v-for="(item,index) in frceArr" :key="index" v-show="index>45&&index<=60">
|
|
|
- <img
|
|
|
- class="memeImg"
|
|
|
- :src="require(`@/assets/${index}.gif`)"
|
|
|
- @click="memeImg(index)"
|
|
|
- >
|
|
|
- </li>
|
|
|
- </ul>
|
|
|
- </div>
|
|
|
- </yd-slider-item>
|
|
|
- <yd-slider-item>
|
|
|
- <div>
|
|
|
- <ul style="width:100%;padding-bottom:.3rem;" class="row average wrap">
|
|
|
- <li v-for="(item,index) in frceArr" :key="index" v-show="index>60">
|
|
|
- <img
|
|
|
- class="memeImg"
|
|
|
- :src="require(`@/assets/${index}.gif`)"
|
|
|
- @click="memeImg(index)"
|
|
|
- >
|
|
|
- </li>
|
|
|
- </ul>
|
|
|
- </div>
|
|
|
- </yd-slider-item>
|
|
|
- </yd-slider>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 留言知识库 -->
|
|
|
- <div v-if="knowledge">
|
|
|
- <!-- 接收返回消息 -->
|
|
|
- <knowledgeLibrary @returnIndex="returnIndex" :currentTime="currentTime"/>
|
|
|
- </div>
|
|
|
- <!-- 发送消息音频提示
|
|
|
- <audio id="send" src="../../static/send.wav"></audio>
|
|
|
- 接收消息音频提示
|
|
|
- <audio id="receive" src="../../static/receive.wav"></audio>
|
|
|
- -->
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script>
|
|
|
- import "../css/index.css";
|
|
|
- import knowledgeLibrary from './knowledgeLibrary'
|
|
|
- import frce from "./frce.js";
|
|
|
- import defaultImgs from "./../assets/timg.jpg"
|
|
|
- import headPortrait from "./../assets/headPortrait.png"
|
|
|
- import autoTextarea from 'auto-textarea'
|
|
|
- import { Loading } from 'vue-ydui/dist/lib.rem/dialog';
|
|
|
- export default {
|
|
|
- name: "service",
|
|
|
- // 模板注册
|
|
|
- components: {
|
|
|
- knowledgeLibrary,
|
|
|
- autoTextarea
|
|
|
- },
|
|
|
- data() {
|
|
|
- return {
|
|
|
- /*-----------------------------------------------*/
|
|
|
- text_info: "", //输入框内容
|
|
|
- knowledge: false,//留言知识库开关
|
|
|
- leftShow: false, //左侧详细开关
|
|
|
- evaluateOnOff: false, //人工客服评价通知
|
|
|
- bottomShow: false, //底部评价弹窗开关
|
|
|
- meme: false, // 表情包开关
|
|
|
- frceArr: [], //表情包代码
|
|
|
- evaluateState: 100,//评价状态
|
|
|
- websock: null,//创建websock
|
|
|
- user_info: '',//用户信息
|
|
|
- apiToken: '',//通话调用凭证
|
|
|
- currentTime: '',//接口调用服务器时间
|
|
|
- problem: [],//机器人问题
|
|
|
- welcome: [],//欢迎语
|
|
|
- advertisement: '', //广告
|
|
|
- img_http: 'https://manage.281570.com',//图片路径域
|
|
|
- //img_http:'http://192.168.2.186:8090',//图片路径域
|
|
|
-
|
|
|
- robot: [],//和机器人聊天临时数据
|
|
|
- chat: [],//人工会话
|
|
|
- error_num: 1001,//机器人回答超出能力之外编号
|
|
|
- isConnection: true,//人工分组列表开关
|
|
|
- ibox_height:'auto',
|
|
|
- //客服信息
|
|
|
- service_info: {
|
|
|
- avatar: headPortrait,
|
|
|
- job_name: '001',
|
|
|
- name: '智能客服',
|
|
|
- signature: ""
|
|
|
- },
|
|
|
- link_success: false,//人工链接成功
|
|
|
- service_on: true,
|
|
|
- closeByServer: false, //客服关闭会话
|
|
|
- serverNotOnlin: false, //客服掉线
|
|
|
- willOverTime: false, //超时关闭会话
|
|
|
- overTimeMsg: '', // 超时提示内容
|
|
|
- conversationId: '',//会话工单
|
|
|
- chatNum: 0,//触发评价按钮条件
|
|
|
- haveEvaluation: false,//是否已评价
|
|
|
- evalArea: '', //评价备注
|
|
|
- source: {},//来源信息
|
|
|
- initData: 1,//
|
|
|
- isTurnArtifcial: true,
|
|
|
- Chrome_height: false, // chrome浏览器增加会话框高度
|
|
|
- Safari_height:false, // 苹果浏览器增加会话框高度
|
|
|
- logo: '',
|
|
|
- isExit: false,
|
|
|
- historyMsg: false, // 是否展示历史信息
|
|
|
- historyMsgtext: "", // 历史信息内容提示
|
|
|
- hisSviceChat: [],
|
|
|
- showHistory: true,
|
|
|
- avatar_imgs: headPortrait,
|
|
|
- webTime: '',//人工会话上一次发送消息时间
|
|
|
- chatIndex: '',//人工会话上一次下标
|
|
|
- /*****************websockt心跳变量*******************/
|
|
|
- reconnectData: null,
|
|
|
- lockReconnect: false, //避免重复连接,因为onerror之后会立即触发 onclose
|
|
|
- timeout: 5000, //5s一次心跳检测
|
|
|
- timeoutObj: null,
|
|
|
- serverTimeoutObj: null,
|
|
|
- waitingMsg: false, // 是否显示等待排队
|
|
|
- serviceNotOnlineText: '',
|
|
|
- comtSuccess:false,
|
|
|
- hisLength:0,
|
|
|
- trueImg:false,
|
|
|
- innerHeight: 0, // 可视区域高度,不包括键盘
|
|
|
- areaHeight: 0, // textarea高度
|
|
|
- loadingobj:null,//加载特效对像
|
|
|
- };
|
|
|
- },
|
|
|
- created() {
|
|
|
- this.getInnerHeight();
|
|
|
- },
|
|
|
- // 方法
|
|
|
- methods: {
|
|
|
- // 获取初始的可视高度
|
|
|
- getInnerHeight() {
|
|
|
- console.log('当前高度:', window.innerHeight)
|
|
|
- this.innerHeight = window.innerHeight;
|
|
|
- },
|
|
|
- // 光标
|
|
|
- // // 退出聊天
|
|
|
- is_exit() {
|
|
|
- this.webTime = ''
|
|
|
- this.socket_send(JSON.stringify({
|
|
|
- type: 'kfCloseUser',
|
|
|
- data: {
|
|
|
- to_id: this.user_info.id,
|
|
|
- kf_id: this.service_info.id,
|
|
|
- group_id: this.service_info.group,
|
|
|
- conversationId: this.conversationId,
|
|
|
- type: 6,
|
|
|
- }
|
|
|
- }));
|
|
|
- this.setInit();
|
|
|
-
|
|
|
- },
|
|
|
- nloding(msg){
|
|
|
- this.$dialog.loading.open(msg);
|
|
|
- },
|
|
|
- closeNloading(){
|
|
|
- this.$dialog.loading.close();
|
|
|
- },
|
|
|
- /*******************************************/
|
|
|
- //设置token加密
|
|
|
- setApiToken(name, controller, time, modules) {
|
|
|
- //let txetVal = name + 'customer-service' + controller + time + modules;
|
|
|
- let txetVal = name + 'customer-service' + controller + modules;
|
|
|
- let sssd = txetVal.toLowerCase();
|
|
|
- return this.$md5(txetVal.toLowerCase());
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************/
|
|
|
- //初始化Websocket链接
|
|
|
- initWebSocket(apiToken) {
|
|
|
- let sock_ip = ''; // 线上
|
|
|
- this.websock = new WebSocket("wss://link.281570.com?apiToken=" + apiToken);
|
|
|
- //数据返回
|
|
|
- this.websock.onmessage = this.socket_message;
|
|
|
- //数据发送
|
|
|
- this.websock.onopen = this.socket_open;
|
|
|
- //重新链接
|
|
|
- this.websock.onerror = this.socket_error;
|
|
|
- //关闭链接
|
|
|
- this.websock.onclose = this.socket_close;
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************/
|
|
|
- //连接建立之后执行send方法发送数据
|
|
|
- socket_open() {
|
|
|
- console.log('我链接了');
|
|
|
- this.$dialog.loading.close();
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************/
|
|
|
- //连接建立失败重连
|
|
|
- socket_error() {
|
|
|
- console.log('连接建立失败重连');
|
|
|
- // this.initWebSocket();
|
|
|
- // this.setInit();
|
|
|
- // this.reconnect();
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************/
|
|
|
- //数据接收
|
|
|
- socket_message(e) {
|
|
|
- if (!e.data) return;
|
|
|
- const redata = JSON.parse(e.data);
|
|
|
- //心跳检测
|
|
|
- this.heatBeat();
|
|
|
- // 心跳检测
|
|
|
- if (redata.message_type == "ping") {
|
|
|
- this.websock.send('{"type":"pong"}')
|
|
|
- return false;
|
|
|
- }
|
|
|
- if (redata.type == 'pong') return false;
|
|
|
-
|
|
|
- if (redata.type != 'pong' || redata.message_type != "ping") {
|
|
|
- console.log(redata)
|
|
|
- }
|
|
|
- //欢迎语
|
|
|
- if (redata.message_type == 'helloMessage') {
|
|
|
- this.isTurnArtifcial = true;
|
|
|
- if (this.initData == 1) {
|
|
|
- this.welcome.push(redata.data.content);
|
|
|
- //this.welcome.push('请点击您想咨询的问题,若都不是,请在输入框直接输入');
|
|
|
- }
|
|
|
- }
|
|
|
- //广告语
|
|
|
- if (redata.message_type == 'advertisement') {
|
|
|
- this.advertisement = redata.data[0]
|
|
|
- }
|
|
|
-
|
|
|
- //机器人回复
|
|
|
- if (redata.message_type == "robotMessage") {
|
|
|
- // console.log(redata);
|
|
|
- if (redata.data.content == "error") {
|
|
|
- this.robot.push({
|
|
|
- type: 'error',
|
|
|
- content: {text: "您的问题暂无法处理"}
|
|
|
- })
|
|
|
- // this.error_num++;
|
|
|
- } else {
|
|
|
- this.robot.push({
|
|
|
- type: 'service',
|
|
|
- content: {text: redata.data.content}
|
|
|
- })
|
|
|
- }
|
|
|
- //console.log(this.robot);
|
|
|
- // this.automaticRolling();
|
|
|
- //data
|
|
|
- //this.robot =
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- //人工链接
|
|
|
- if (redata.message_type == 'connect') {
|
|
|
- this.willOverTime = false;
|
|
|
- this.trueImg = true
|
|
|
- this.chat.splice(-1)
|
|
|
- let server = {};
|
|
|
- if (redata.data) {
|
|
|
- server = redata.data
|
|
|
- } else {
|
|
|
- server = {
|
|
|
- conversationId: redata.data.conversationId,
|
|
|
- kf_id: redata.data.kf_id,
|
|
|
- kf_name: "",
|
|
|
- serverInfo: {
|
|
|
- avatar: avatarImgs,
|
|
|
- client_id: "",
|
|
|
- group: "",
|
|
|
- id: "",
|
|
|
- intime: "",
|
|
|
- job_name: "",
|
|
|
- name: "tank",
|
|
|
- signature: "",
|
|
|
- status: 0,
|
|
|
- task: 0,
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
- this.service_on = true;
|
|
|
- this.isExit = true;
|
|
|
- this.link_success = true;
|
|
|
- // localStorage.getItem('comtSuccess',true)
|
|
|
- this.$dialog.loading.close();
|
|
|
- this.service_info = server.serverInfo;
|
|
|
- this.conversationId = server.conversationId;
|
|
|
- }
|
|
|
-
|
|
|
- // 客服掉线.
|
|
|
- if (redata.message_type == 'serviceoffline') {
|
|
|
- this.chat.push({
|
|
|
- type: 'system',
|
|
|
- content: {
|
|
|
- text: redata.msg,
|
|
|
- state: 'closeInform',
|
|
|
- }
|
|
|
- })
|
|
|
- this.automaticRolling();
|
|
|
- this.service_on = false;
|
|
|
- // let that = this;
|
|
|
- // setTimeout(function () {
|
|
|
- // that.link_success = false;
|
|
|
- // that.serverNotOnlin = true;
|
|
|
- // that.closeByServer = true;
|
|
|
- // that.chat.splice(-1)
|
|
|
- // },3000)
|
|
|
-
|
|
|
- }
|
|
|
- // 客服不在线请稍后再试
|
|
|
- if (redata.message_type == 'kfNotOnlin') {
|
|
|
- this.service_on = false;
|
|
|
- }
|
|
|
-
|
|
|
- // 客服会话超时
|
|
|
- if (redata.message_type == 'overtime') {
|
|
|
- this.willOverTime = true;
|
|
|
- this.automaticRolling();
|
|
|
- // this.goBack();
|
|
|
- this.overTimeMsg = redata.data.content;
|
|
|
- }
|
|
|
-
|
|
|
- // 客服等待排队
|
|
|
- if (redata.message_type == "inqueue") {
|
|
|
- this.waitingMsg = true;
|
|
|
- // this.automaticRolling();
|
|
|
- // this.waitingText = redata.content;
|
|
|
- this.$dialog.confirm({
|
|
|
- title: '温馨提示',
|
|
|
- mes: redata.content,
|
|
|
- opts: [{
|
|
|
- txt: '取消排队',
|
|
|
- color: true,
|
|
|
- callback: () => {
|
|
|
-
|
|
|
- this.socket_send(JSON.stringify({
|
|
|
- "type": "cancelqueue",
|
|
|
- "data": {
|
|
|
- "uid": localStorage.getItem('uid')
|
|
|
- }
|
|
|
- }));
|
|
|
- this.isTurnArtifcial =true;
|
|
|
- // this.$dialog.toast({mes: '你点了确定', timeout: 1000});
|
|
|
- }
|
|
|
- }]
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- //人工会话回复
|
|
|
- if (redata.message_type == "chatMessage") {
|
|
|
- // 转接的时候清除历史信息
|
|
|
- // this.hisSviceChat = [];
|
|
|
- // this.getHistory = false;
|
|
|
- // 接收提示音
|
|
|
- this.receiveAudio();
|
|
|
- this.$dialog.loading.close();
|
|
|
- let obj = {};
|
|
|
- let thisTime = '';
|
|
|
- if (this.$public.isJSON(redata.data.content)) {
|
|
|
- obj = JSON.parse(redata.data.content);
|
|
|
- obj.text = this.turnFace(obj.text);
|
|
|
- //接收消息大于两分钟显示时间
|
|
|
- let newTime = redata.data.time.split(':');
|
|
|
- if (this.webTime) {
|
|
|
- let lastTime = this.webTime.split(":");
|
|
|
- if (newTime[0] == lastTime[0] && newTime[1] < (lastTime[1] + 2)) {
|
|
|
- thisTime = ''
|
|
|
- } else {
|
|
|
- thisTime = redata.data.time;
|
|
|
- }
|
|
|
- } else {
|
|
|
- thisTime = redata.data.time;
|
|
|
- }
|
|
|
- this.webTime = redata.data.time;
|
|
|
- } else {
|
|
|
- obj.text = redata.data.content;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- this.chat.push({
|
|
|
- type: 'service',
|
|
|
- time: thisTime ? thisTime : '',
|
|
|
- content: obj
|
|
|
- })
|
|
|
- }
|
|
|
- //系统消息通知客户结束通话
|
|
|
- if (redata.message_type == 'closeBysever') {
|
|
|
- this.setInit();
|
|
|
- this.showHistory = false;
|
|
|
- this.link_success = false;
|
|
|
- this.isTurnArtifcial = true;
|
|
|
- localStorage.removeItem('comtSuccess');
|
|
|
- this.comtSuccess = false;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if (redata.message_type == "changeKeFuSuccess") {
|
|
|
- this.$dialog.alert({
|
|
|
- mes: redata.data.content
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- //系统消息通转人工
|
|
|
- if (redata.message_type == 'notice') {
|
|
|
- console.log('人工');
|
|
|
- this.$dialog.loading.close();
|
|
|
- this.isTurnArtifcial = true;
|
|
|
- let _this = this;
|
|
|
- this.$dialog.alert({
|
|
|
- mes: redata.content, callback: () => {
|
|
|
- this.initData = 100;
|
|
|
- // _this.$dialog.loading.open('数据加载中...');
|
|
|
- // setTimeout(() => {
|
|
|
- // _this.$dialog.loading.close();
|
|
|
- // // _this.registered();
|
|
|
- // }, 2000);
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- //系统消息评价
|
|
|
- if (redata.message_type == "getEvaluate") {
|
|
|
- // this.evaluateOnOff = true;
|
|
|
- // console.log( this.chat)
|
|
|
- this.chat.push({
|
|
|
- type: 'system',
|
|
|
- content: {
|
|
|
- text: redata.data.content,
|
|
|
- state: 'getEvaluate',
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- //会话关闭前通知用户
|
|
|
- if (redata.message_type == 'overtime') {
|
|
|
- this.chat.push({
|
|
|
- type: 'system',
|
|
|
- content: {
|
|
|
- text: redata.data.content,
|
|
|
- state: 'closeInform',
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- // 历史信息
|
|
|
- if (redata.message_type == 'toOld') {
|
|
|
- this.hisSviceChat = [];
|
|
|
- let obj = redata;
|
|
|
- this.historyMsgtext = obj.data.content;
|
|
|
- this.chat.push({
|
|
|
- type: 'historyMsg',
|
|
|
- content: {
|
|
|
- text: this.historyMsgtext,
|
|
|
- }
|
|
|
- })
|
|
|
- let historyTime = '';
|
|
|
- this.hisLength =obj.data.chatLog.length
|
|
|
- obj.data.chatLog.forEach(res => {
|
|
|
- // console.log(res,'历史信息');
|
|
|
- res.content = JSON.parse(res.content);
|
|
|
- res.content.text =this.turnFace(res.content.text);
|
|
|
- let time_line = this.$public.customFormatDateTime(res.time_line, '', 3);
|
|
|
- if (!historyTime) {
|
|
|
- res.time_line = time_line
|
|
|
- } else {
|
|
|
- let newTime = time_line.split(':');
|
|
|
- let lastTime = historyTime.split(':');
|
|
|
- if (newTime[0] == lastTime[0] && newTime[1] < (lastTime[1] + 2)) {
|
|
|
- res.time_line = '';
|
|
|
- } else {
|
|
|
- res.time_line = time_line
|
|
|
- }
|
|
|
- }
|
|
|
- // console.log(res.content);
|
|
|
- historyTime = time_line;
|
|
|
- this.hisSviceChat.push(res);
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- //获取发送时间
|
|
|
- if (redata.message_type == "webTime") {
|
|
|
- // console.log(this.chat)
|
|
|
- // console.log(this.chatIndex)
|
|
|
- if (this.webTime) {
|
|
|
- let newTime = redata.data.webTime.split(':');
|
|
|
- let time = this.webTime.split(':');
|
|
|
-
|
|
|
- if (newTime[0] * 1 > time[0] * 1) {
|
|
|
- // console.log('newTime[0]')
|
|
|
- this.$set(this.chat[this.chatIndex], 'time', redata.data.webTime);
|
|
|
- } else if (newTime[0] * 1 == time[0] * 1 && (newTime[1] * 1 - time[1] * 1) > 2) {
|
|
|
- this.$set(this.chat[this.chatIndex], 'time', redata.data.webTime);
|
|
|
- // console.log('newTime[1]')
|
|
|
- }
|
|
|
- } else {
|
|
|
- this.$set(this.chat[this.chatIndex],'time',redata.data.webTime);
|
|
|
- }
|
|
|
- this.webTime = redata.data.webTime
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- // 评价返回
|
|
|
- if (redata.message_type == "evaluate") {
|
|
|
- if (redata.data.status == 1) {
|
|
|
- this.comtSuccess = true;
|
|
|
- localStorage.setItem('comtSuccess',true)
|
|
|
- }
|
|
|
- }
|
|
|
- //屏幕滚动
|
|
|
- this.automaticRolling();
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************/
|
|
|
- //数据发送
|
|
|
- socket_send(Data) {
|
|
|
- this.websock.send(Data);
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- /*******************************************/
|
|
|
- //关闭
|
|
|
- socket_close(e) {
|
|
|
- console.log('断开连接', e);
|
|
|
- this.nloding('网络接中...');
|
|
|
- this.initData = 100;
|
|
|
- this.link_success = false;
|
|
|
- this.setInit();
|
|
|
- this.reconnect();
|
|
|
- // this.registered();
|
|
|
- // this.websock.close()
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- /***************************************/
|
|
|
- //socket重连
|
|
|
- reconnect() {
|
|
|
- if (this.lockReconnect) { //这里很关键,因为连接失败之后之后会相继触发 连接关闭,不然会连接上两个 WebSocket
|
|
|
- return
|
|
|
- }
|
|
|
- this.lockReconnect = true;
|
|
|
- this.reconnectData && clearTimeout(this.reconnectData);
|
|
|
- this.reconnectData = setTimeout(() => {
|
|
|
- this.initWebSocket(this.apiToken);
|
|
|
- //this.registered()
|
|
|
- // console.log('-----lail-----');
|
|
|
- this.lockReconnect = false;
|
|
|
- }, 2000)
|
|
|
- },
|
|
|
-
|
|
|
- /*************************************/
|
|
|
- //心跳检测
|
|
|
- heatBeat() {
|
|
|
- this.timeoutObj && clearTimeout(this.timeoutObj);
|
|
|
- this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
|
|
|
- this.timeoutObj = setTimeout(() => {
|
|
|
- // console.log('发送', {type: 'ping'});
|
|
|
- this.socket_send(JSON.stringify({type: 'ping'})) //根据后台要求发送
|
|
|
- this.serverTimeoutObj = setTimeout(() => {
|
|
|
- // console.log('------close-------')
|
|
|
- this.websock.close(); //如果 4秒之后我们没有收到 后台返回的心跳检测数据 断开socket,断开后会启动重连机制
|
|
|
- }, 4000);
|
|
|
- }, this.timeout)
|
|
|
- },
|
|
|
-
|
|
|
- /*****************************************/
|
|
|
- //用户匿名注册
|
|
|
- registered() {
|
|
|
- let token = localStorage.getItem('token');
|
|
|
- let appuid = this.$public.getQueryString('appuid');
|
|
|
- let tutype = this.$public.getQueryString('tutype');
|
|
|
- if (appuid && tutype >= 1) {
|
|
|
- token = localStorage.getItem('token');
|
|
|
- } else if (!appuid && tutype < 1) {
|
|
|
- token = localStorage.getItem('token');
|
|
|
- } else {
|
|
|
- token = '';
|
|
|
- }
|
|
|
- let data = {
|
|
|
- token: token != null ? token : '',
|
|
|
- appid: this.$public.getQueryString('appid'),
|
|
|
- appuid: this.$public.getQueryString('appuid'),
|
|
|
- }
|
|
|
- let obj = {
|
|
|
- headers: {
|
|
|
- "apiToken": this.setApiToken('autoReg', 'register', this.currentTime[0], 'index')
|
|
|
- }
|
|
|
- }
|
|
|
- this.$http.post('/index/register/autoReg', data, obj).then(res => {
|
|
|
- if (res.data.code == 0) {
|
|
|
- this.$dialog.alert({
|
|
|
- mes: res.data.msg
|
|
|
- });
|
|
|
- } else if (res.data.code == 1) {
|
|
|
- this.user_info = res.data.data;
|
|
|
- // console.log(this.user_info)
|
|
|
- localStorage.setItem('uid', res.data.data.id)
|
|
|
- // 游客 token
|
|
|
- localStorage.setItem("token", res.data.data.token);
|
|
|
- localStorage.setItem("tutype", res.data.tutype);
|
|
|
- //Websocket链接
|
|
|
-
|
|
|
- this.$dialog.loading.close();
|
|
|
- this.initWebSocket(this.apiToken);
|
|
|
- //console.log(res.data.data)
|
|
|
- }
|
|
|
- })
|
|
|
- },
|
|
|
-
|
|
|
- /******************************************/
|
|
|
- //获取热门问题
|
|
|
- getProblem() {
|
|
|
- let obj = {
|
|
|
- headers: {
|
|
|
- // 'Content-Type': 'application/x-www-form-urlencoded',
|
|
|
- "apiToken": this.setApiToken('index', 'robot', this.currentTime[0], 'index')
|
|
|
- }
|
|
|
- }
|
|
|
- this.$http.post('/index/robot/index', {groups_id: 1, robotgroups_id: 1}, obj).then(res => {
|
|
|
- //console.log(res.data.data);
|
|
|
- this.problem = res.data.data;
|
|
|
- })
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************/
|
|
|
- //推送机器人消息
|
|
|
- pushMessage(e) {
|
|
|
- this.robot.push({
|
|
|
- type: 'service',
|
|
|
- content: {text: e}
|
|
|
- });
|
|
|
- this.automaticRolling();
|
|
|
- },
|
|
|
- checkSetType(){
|
|
|
- let u = navigator.userAgent, app = navigator.appVersion;
|
|
|
- let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //g
|
|
|
- let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
|
|
|
- if (isAndroid) {
|
|
|
- return 'android';
|
|
|
- }
|
|
|
- if (isIOS) {
|
|
|
- return 'ios';
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************/
|
|
|
- //转人工
|
|
|
- turnArtificial(id) {
|
|
|
- this.group = id;
|
|
|
- // this.$dialog.loading.open('转接中...')
|
|
|
- this.nloding('人工客服转接中');
|
|
|
-
|
|
|
-
|
|
|
- if (this.isTurnArtifcial) {
|
|
|
-
|
|
|
- let data = {
|
|
|
- 'type': 'userInit',
|
|
|
- data: {
|
|
|
- 'uid': this.user_info.id,
|
|
|
- 'name': this.user_info.name,
|
|
|
- 'avatar': this.user_info.avatar,
|
|
|
- 'group': this.group,
|
|
|
- 'settype':this.checkSetType()
|
|
|
- }
|
|
|
- }
|
|
|
- this.socket_send(JSON.stringify(data));
|
|
|
- this.isTurnArtifcial = false
|
|
|
- // if(){
|
|
|
- // }else{
|
|
|
- // setTimeout(()=>{
|
|
|
- // this.socket_send(JSON.stringify(data));
|
|
|
- // this.isTurnArtifcial = false
|
|
|
- // })
|
|
|
- // }
|
|
|
-
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /******************************************/
|
|
|
- // 消息发送
|
|
|
- send() {
|
|
|
- if (this.text_info == '') return;
|
|
|
- let str = this.text_info;
|
|
|
- let formatStr = str.replace(/\n|\r\n/g, "<br>");
|
|
|
- let type = 'toRobot';
|
|
|
- let data = {};
|
|
|
- let obj = {
|
|
|
- text: formatStr,
|
|
|
- img: '',
|
|
|
- type: ''
|
|
|
- }
|
|
|
- this.meme = false;
|
|
|
- // console.log(JSON.stringify(obj))
|
|
|
- //和人工发送消息
|
|
|
- if (this.link_success) {
|
|
|
- // if(this.getHistory){
|
|
|
- // this.getHistory = false;
|
|
|
- // }
|
|
|
- data = {
|
|
|
- from_name: this.user_info.name,
|
|
|
- content: JSON.stringify(obj),
|
|
|
- from_id: this.user_info.id,
|
|
|
- avatar: '',
|
|
|
- to_id: this.service_info.id,
|
|
|
- to_name: this.service_info.name,
|
|
|
- conversationId: this.conversationId,
|
|
|
- }
|
|
|
- type = 'chatMessage';
|
|
|
- this.chatIndex = this.chat.length;
|
|
|
- this.chat.push({
|
|
|
- type: 'user',
|
|
|
- time: '',
|
|
|
- content: {text: this.turnFace(obj.text)}
|
|
|
- })
|
|
|
- } else {//和机器人聊天
|
|
|
- data = {
|
|
|
- groups_id: '1',
|
|
|
- robot_name: formatStr,
|
|
|
- robotgroups_id: '1',
|
|
|
- }
|
|
|
- // console.log(this.turnFace(formatStr));
|
|
|
- type = 'toRobot';
|
|
|
- //本地存放数据
|
|
|
- this.robot.push({
|
|
|
- type: 'user',
|
|
|
- content: this.turnFace(formatStr) //obj
|
|
|
- })
|
|
|
- }
|
|
|
- this.socket_send(JSON.stringify({type, data}))
|
|
|
- this.text_info = '';
|
|
|
- this.automaticRolling();
|
|
|
- // console.log(data)
|
|
|
- this.sendAudio();
|
|
|
- // 还原输入框高度
|
|
|
- let area = document.getElementById('textarea')
|
|
|
- area.style.height = 36 + 'px';
|
|
|
- },
|
|
|
-
|
|
|
- // 消息发送音频
|
|
|
- sendAudio() {
|
|
|
- let send = new Audio();
|
|
|
- send.src = '../../static/audio/send.wav';
|
|
|
- send.play()
|
|
|
- },
|
|
|
- // 消息接收音频
|
|
|
- receiveAudio() {
|
|
|
- let receive = new Audio()
|
|
|
- receive.src = "../../static/audio/receive.wav";
|
|
|
- receive.play();
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************/
|
|
|
- //获取转接人工客服列表
|
|
|
- connectionService() {
|
|
|
- // if (!this.isConnection) return
|
|
|
- this.nloding('正在读取客服列表');
|
|
|
- let obj = {
|
|
|
- headers: {
|
|
|
- "apiToken": this.setApiToken('index', 'groups', this.currentTime[0], 'index')
|
|
|
- }
|
|
|
- }
|
|
|
- // this.isConnection = false;
|
|
|
- //api
|
|
|
- this.$http.get('/index/groups/index', obj).then(res => {
|
|
|
- this.closeNloading();
|
|
|
- if (res.data.code == 1) {
|
|
|
- this.robot.push({
|
|
|
- type: 'artificial_service',
|
|
|
- content: res.data.data
|
|
|
- });
|
|
|
- this.automaticRolling();
|
|
|
- }
|
|
|
- })
|
|
|
- //this.hintSwitch.connection = true; //系统提示开关激活
|
|
|
- // 此处为请求
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************/
|
|
|
- //发送消息后自动滚动高度
|
|
|
- automaticRolling() {
|
|
|
- this.$nextTick(() => {
|
|
|
- let msg = document.getElementById('main') // 获取对象
|
|
|
- // let input_box = document.getElementById('input_box') // 获取对象
|
|
|
-
|
|
|
- //判断是否是苹果手机自代浏览器
|
|
|
- if (/iPhone/.test(navigator.userAgent)) {
|
|
|
- this.Safari_height = true; //input_box+'px';
|
|
|
- }
|
|
|
- if (/Linux/.test(navigator.userAgent)) {
|
|
|
- this.Chrome_height = true; //input_box+'px';
|
|
|
- }
|
|
|
-
|
|
|
- msg.scrollTop = msg.scrollHeight // 滚动高度
|
|
|
-
|
|
|
- })
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************/
|
|
|
- //图片发送
|
|
|
- uploadIMG(e) {
|
|
|
- // console.log(e);
|
|
|
-
|
|
|
- let self = this;
|
|
|
- let files = e.target.files || e.dataTransfer.files;
|
|
|
- if (!files.length) return;
|
|
|
- let picavalue = files[0];
|
|
|
- const isJPG = file.type == 'image/jpeg' || 'image/jpg' || 'image/png' || 'image/svg';
|
|
|
- const isLt2M = picavalue.size / 1000 / 1000 > 2;
|
|
|
-
|
|
|
- if (isLt2M) {
|
|
|
- this.$dialog.notify({
|
|
|
- mes: '图片过大不支持上传哦!',
|
|
|
- timeout: 2000,
|
|
|
- });
|
|
|
- } else if (!isJPG) {
|
|
|
- this.$dialog.notify({
|
|
|
- mes: '只能上传图片哦!',
|
|
|
- timeout: 2000,
|
|
|
- });
|
|
|
- } else {
|
|
|
- this.$public.imgPreview(picavalue, function (imgSrc, formData) {
|
|
|
- // let img = imgSrc;
|
|
|
- // 数据结构请求
|
|
|
- self.$http.uploadPost('/index/upload/uploadImg', formData).then(res => {
|
|
|
- e.target.value = "";
|
|
|
- // console.log(res.data.code)
|
|
|
- if (res.data.code == 1) {
|
|
|
- let type = 'toRobot';
|
|
|
- let data = {};
|
|
|
- let obj = {
|
|
|
- text: '',
|
|
|
- img: res.data.data.src,
|
|
|
- type: ''
|
|
|
- }
|
|
|
- if (self.link_success) {
|
|
|
- //和人工聊天发送图片
|
|
|
- data = {
|
|
|
- from_name: self.user_info.name,
|
|
|
- content: JSON.stringify(obj),
|
|
|
- from_id: self.user_info.id,
|
|
|
- avatar: '',
|
|
|
- to_id: self.service_info.id,
|
|
|
- to_name: self.service_info.name,
|
|
|
- conversationId: self.conversationId,
|
|
|
- }
|
|
|
- type = 'chatMessage';
|
|
|
-
|
|
|
- self.chatIndex = self.chat.length;
|
|
|
- //本地储存
|
|
|
- self.chat.push({
|
|
|
- type: 'user',
|
|
|
- time:"",
|
|
|
- content: {img: res.data.data.src}
|
|
|
- });
|
|
|
-
|
|
|
-
|
|
|
- } else {
|
|
|
- //和机器发送图片
|
|
|
- data = {
|
|
|
- groups_id: '1',
|
|
|
- robot_name: res.data.data.src,
|
|
|
- robotgroups_id: '1',
|
|
|
- }
|
|
|
- type = 'toRobot';
|
|
|
- //本地储存
|
|
|
- self.robot.push({
|
|
|
- type: 'user',
|
|
|
- content: {img: res.data.data.src}
|
|
|
- });
|
|
|
- }
|
|
|
- self.socket_send(JSON.stringify({type, data}))
|
|
|
- self.automaticRolling();
|
|
|
- }
|
|
|
- })
|
|
|
- });
|
|
|
- }
|
|
|
- },
|
|
|
- /**监听滚动事件,使消息能完全看见 */
|
|
|
- scrollMain() {
|
|
|
- let main = document.getElementById('main')
|
|
|
- let footer = document.getElementById('input_box')
|
|
|
- main.style.bottom = 0;
|
|
|
- main.style.paddingBottom = (footer.offsetHeight - 30) + 'px'
|
|
|
- },
|
|
|
- /** 监听输入框滚动高度,并给textarea高度赋值*/
|
|
|
- keyup_maxlength(){
|
|
|
- let area = document.getElementById('textarea')
|
|
|
- this.areaHeight = area.scrollHeight > 36 ? area.scrollHeight : 36;
|
|
|
- let main = document.getElementById('main')
|
|
|
- this.makeExpandingArea(area)
|
|
|
- //console.log('screen:', window.screen.height, 'inner:', window.innerHeight)
|
|
|
- // main.style.bottom = this.needScrollTop + 'px'
|
|
|
- // console.log('foucus', this.needScrollTop)
|
|
|
- // this.automaticRolling();
|
|
|
- },
|
|
|
- focus_maxlength() {
|
|
|
- this.automaticRolling();
|
|
|
- },
|
|
|
- /** 兼容处理 */
|
|
|
- makeExpandingArea(el) {
|
|
|
- var timer = null;
|
|
|
- //由于ie8有溢出堆栈问题,故调整了这里
|
|
|
- var setStyle = function(el, auto) {
|
|
|
- if (auto) el.style.height = 'auto';
|
|
|
- el.style.height = el.scrollHeight + 'px';
|
|
|
- }
|
|
|
- var delayedResize = function(el) {
|
|
|
- if (timer) {
|
|
|
- clearTimeout(timer);
|
|
|
- timer = null;
|
|
|
- }
|
|
|
- timer = setTimeout(function() {
|
|
|
- setStyle(el)
|
|
|
- }, 200);
|
|
|
- }
|
|
|
- if (el.addEventListener) {
|
|
|
- el.addEventListener('input', function() {
|
|
|
- setStyle(el, 1);
|
|
|
- }, false);
|
|
|
- setStyle(el)
|
|
|
- } else if (el.attachEvent) {
|
|
|
- el.attachEvent('onpropertychange', function() {
|
|
|
- setStyle(el)
|
|
|
- })
|
|
|
- setStyle(el)
|
|
|
- }
|
|
|
- if (window.VBArray && window.addEventListener) { //IE9
|
|
|
- el.attachEvent("onkeydown", function() {
|
|
|
- var key = window.event.keyCode;
|
|
|
- if (key == 8 || key == 46) delayedResize(el);
|
|
|
-
|
|
|
- });
|
|
|
- el.attachEvent("oncut", function() {
|
|
|
- delayedResize(el);
|
|
|
- }); //处理粘贴
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- /*******************************************/
|
|
|
- //手机弹窗处理
|
|
|
- inputShow(e) {
|
|
|
- //console.log('a')
|
|
|
- let ua = navigator.userAgent.toLowerCase();
|
|
|
- if (ua.match(/iPhone\sOS/i) == "iphone os") {
|
|
|
- var nowClientHeight = document.documentElement.clientHeight || document.body.clientHeight;
|
|
|
-
|
|
|
- setTimeout(() => {
|
|
|
- document.body.scrollTop = document.body.scrollHeight - (nowClientHeight / 2)
|
|
|
- }, 200);
|
|
|
- } else {
|
|
|
- setTimeout(function () {
|
|
|
- e.target.scrollIntoView({behavior: "smooth", block: "end"});
|
|
|
- }, 100);
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /******************文字信息转表情******************/
|
|
|
- turnFace(data) {
|
|
|
- let str = data.match(/\#\[.*?\]\//g);
|
|
|
- let arr = Array.from(new Set(str));
|
|
|
- arr.forEach(e => {
|
|
|
- let imgsrc = '';
|
|
|
- for (let i = 0; i < this.frceArr.length; i++) {
|
|
|
- let expText = e.slice(1, e.length - 1);
|
|
|
- if (expText == this.frceArr[i]) {
|
|
|
- imgsrc = '<img class="hover" src="' + require(`@/assets/${i}.gif`) + '"/>'
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- data = data.replace(new RegExp(`\\#\\[${e.substring(2, e.length - 2)}\\]\\/`, 'g'), imgsrc);
|
|
|
- })
|
|
|
- return data;
|
|
|
- },
|
|
|
-
|
|
|
-
|
|
|
- /*******************************************/
|
|
|
- // 表情包开关
|
|
|
- faceClick() {
|
|
|
- this.meme = !this.meme;
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************/
|
|
|
- //当表情被点击
|
|
|
- memeImg(i) {
|
|
|
- this.text_info = this.text_info + "#" + this.frceArr[i] + "/";
|
|
|
- //this.text_info = this.text_info + '<img :src="' + require(`@/assets/${i}.gif`) +'"/>';
|
|
|
- // console.log( this.text_info);
|
|
|
- },
|
|
|
-
|
|
|
- // /*******************************************/
|
|
|
- // //验证码
|
|
|
- // initialLoginCode() {
|
|
|
- // this.loginCode = "";
|
|
|
- // for (let i = 1; i <= 4; i++) {
|
|
|
- // this.loginCode =
|
|
|
- // this.loginCode + frce.arr[Math.floor(Math.random() * 32)];
|
|
|
- // }
|
|
|
- // },
|
|
|
-
|
|
|
- /********************************************/
|
|
|
- //显示隐藏评价
|
|
|
- is_show_evaluate() {
|
|
|
- if(localStorage.getItem('comtSuccess')){
|
|
|
- this.$dialog.notify({
|
|
|
- mes: '亲,您已经评价了...',
|
|
|
- timeout: 3000,
|
|
|
- });
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- if (this.evaluateState == 100) {
|
|
|
- this.bottomShow = true;
|
|
|
- } else {
|
|
|
- if (!this.haveEvaluation) {
|
|
|
- this.bottomShow = false;
|
|
|
- } else {
|
|
|
- this.$dialog.notify({
|
|
|
- mes: '亲,您已经评价了...',
|
|
|
- timeout: 5000,
|
|
|
- callback: () => {
|
|
|
- //console.log('我走咯!');
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************/
|
|
|
- //切换评价状态
|
|
|
- evaluateClick(type) {
|
|
|
- // console.log(type);
|
|
|
- this.evaluateState = type;
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************/
|
|
|
- //提交评价信息
|
|
|
- evaluateEsc() {
|
|
|
-
|
|
|
- if (this.evaluateState != 100) {
|
|
|
- this.bottomShow = false;
|
|
|
- this.haveEvaluation = true; // 标识已评价
|
|
|
- this.socket_send(JSON.stringify({
|
|
|
- type: 'evaluate', data: {
|
|
|
- evaluate_id: this.evaluateState,
|
|
|
- conversationId: this.conversationId,
|
|
|
- // evaluate_content:''
|
|
|
- }
|
|
|
- }))
|
|
|
- let that = this
|
|
|
- this.$dialog.notify({
|
|
|
- mes: '感谢你的评价!',
|
|
|
- timeout: 2000,
|
|
|
- callback: () => {
|
|
|
- //console.log('我走咯!');
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- } else {
|
|
|
- this.$dialog.notify({
|
|
|
- mes: '亲,请选择评价类型...',
|
|
|
- timeout: 2000,
|
|
|
- callback: () => {
|
|
|
- //console.log('我走咯!');
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /************************************************/
|
|
|
- //人工聊天初始化
|
|
|
- setInit() {
|
|
|
- this.haveEvaluation = false;
|
|
|
- this.chat = [];
|
|
|
- this.evaluateState = 100;
|
|
|
- this.hisSviceChat = [];
|
|
|
- this.meme = false
|
|
|
- // this.frceArr = [];//表情包代码
|
|
|
- this.isConnection = true;
|
|
|
- this.isExit = false;
|
|
|
- this.service_info = {
|
|
|
- avatar: '/static/customer/images/robot.png',
|
|
|
- job_name: '001',
|
|
|
- name: '智能客服',
|
|
|
- signature: " "
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /* ****************获取聊天次数****************** */
|
|
|
- getChatNum() {
|
|
|
- this.$http.get('/index/evaluate/minRound', {
|
|
|
- headers: {
|
|
|
- 'Content-Type': 'application/x-www-form-urlencoded',
|
|
|
- 'apiToken': this.setApiToken('minround', 'evaluate', this.currentTime[0], 'index')
|
|
|
- }
|
|
|
- }).then(res => {
|
|
|
- if (res.data.code == 1) {
|
|
|
- this.chatNum = res.data.data.systemconfig_data;
|
|
|
- // console.log(this.chatNum, '聊天限制')
|
|
|
- }
|
|
|
- })
|
|
|
- },
|
|
|
- // 留言知识库返回到主页
|
|
|
- returnIndex(data) {
|
|
|
- console.log(data)
|
|
|
- this.knowledge = data
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 视图挂载前
|
|
|
- */
|
|
|
- mounted() {
|
|
|
- this.source.appuid = this.$public.getQueryString('appuid');//用户标识
|
|
|
- this.source.appid = this.$public.getQueryString('appid');//用户来源
|
|
|
- this.frceArr = frce.frce;
|
|
|
- //console.log(this.source);
|
|
|
- //页面初始化获取系统时间第一步
|
|
|
- //console.log(this.$md5('userwordscustomer-servicewords1562169600service'));
|
|
|
- this.$dialog.loading.open('网络连接中...');
|
|
|
- this.$http.get('/index/index/systime?t=' + 100).then(res => {
|
|
|
- if (res.data.code == 1) {
|
|
|
- this.logo = res.data.data.logo;
|
|
|
- this.currentTime = res.data.data.time.split(' ')
|
|
|
- this.currentTime[0] = (new Date(this.currentTime[0].replace(/-/g, '/')).getTime()) / 1000;
|
|
|
-
|
|
|
- // console.log( this.currentTime[0] );
|
|
|
- this.apiToken = this.$md5('customer-service' + window.location.origin);
|
|
|
- //匿名注册
|
|
|
- this.registered();
|
|
|
- //获取机器人热门问题
|
|
|
- this.getProblem();
|
|
|
- //获取配置信息
|
|
|
- this.getChatNum();
|
|
|
- }
|
|
|
-
|
|
|
- })
|
|
|
- },
|
|
|
-
|
|
|
- destroyed() {
|
|
|
- this.setInit();
|
|
|
- this.websock.close() //离开路由之后断开websocket连接
|
|
|
- this.lockReconnect = true;
|
|
|
- clearTimeout(this.reconnectData); //离开清除 timeout
|
|
|
- clearTimeout(this.timeoutObj); //离开清除 timeout
|
|
|
- clearTimeout(this.serverTimeoutObj); //离开清除 timeout
|
|
|
- },
|
|
|
- // 计算
|
|
|
- computed: {
|
|
|
- inputmsg() {
|
|
|
- return this.text_info;
|
|
|
- },
|
|
|
- iboxheight(){
|
|
|
- return this.ibox_height;
|
|
|
- },
|
|
|
- // 需要额外滚动的高度,大小为键盘高度加上输入框的高度
|
|
|
- needScrollTop: function () {
|
|
|
- if(this.innerHeight > 0) {
|
|
|
- // return (this.innerHeight > window.innerHeight ? this.innerHeight : innerHeight )
|
|
|
- // - window.innerHeight + this.areaHeight -36
|
|
|
- return window.screen.height - window.innerHeight + this.areaHeight -36
|
|
|
- } else {
|
|
|
- return 0;
|
|
|
- }
|
|
|
- },
|
|
|
- },
|
|
|
- // 监听
|
|
|
- watch: {},
|
|
|
- // 组件生命周期结束销毁阶段
|
|
|
- beforeDestroy() {
|
|
|
- this.timers = false;
|
|
|
- }
|
|
|
- };
|
|
|
-</script>
|
|
|
-
|
|
|
-<style scoped>
|
|
|
- #textarea {
|
|
|
- flex: 1;
|
|
|
- height: 36px;
|
|
|
- margin: 15px;
|
|
|
- border: none;
|
|
|
- }
|
|
|
-
|
|
|
- .logo {
|
|
|
- margin: 0 0.1rem;
|
|
|
- width: 0.4rem;
|
|
|
- height: 0.4rem;
|
|
|
- }
|
|
|
-
|
|
|
- /* 聊天 */
|
|
|
- .memeImg {
|
|
|
- width: 0.6rem;
|
|
|
- height: 0.6rem;
|
|
|
- margin: 0.15rem 0.4rem;
|
|
|
- }
|
|
|
-
|
|
|
- .dialogueA {
|
|
|
- padding-left: 0.3rem;
|
|
|
- padding-right: 0.3rem;
|
|
|
- }
|
|
|
-
|
|
|
- .dialogueB {
|
|
|
- padding-right: 0.3rem;
|
|
|
- padding-left: 0.3rem;
|
|
|
- }
|
|
|
-
|
|
|
- .left {
|
|
|
- position: relative;
|
|
|
- z-index: 99;
|
|
|
- background: #fff;
|
|
|
- }
|
|
|
-
|
|
|
- .left::after {
|
|
|
- position: absolute;
|
|
|
- content: "";
|
|
|
- display: inline-block;
|
|
|
- left: -0.08rem;
|
|
|
- top: 0.2rem;
|
|
|
- width: 0.125rem;
|
|
|
- height: 0.2rem;
|
|
|
- background: #fff;
|
|
|
- transform: skewX(30deg);
|
|
|
- z-index: -1;
|
|
|
- border-left: 0.02rem solid #dfdfdf;
|
|
|
- border-top: 0.02rem solid #dfdfdf;
|
|
|
- }
|
|
|
-
|
|
|
- .right {
|
|
|
- position: relative;
|
|
|
- z-index: 99;
|
|
|
- background: #5ea0f7;
|
|
|
- border: 0.02rem solid #5ea0f7;
|
|
|
- }
|
|
|
-
|
|
|
- .right::after {
|
|
|
- position: absolute;
|
|
|
- content: "";
|
|
|
- display: inline-block;
|
|
|
- right: -0.07rem;
|
|
|
- top: 0.2rem;
|
|
|
- width: 0.125rem;
|
|
|
-
|
|
|
- height: 0.2rem;
|
|
|
- background: #5ea0f7;
|
|
|
- transform: skewX(-30deg);
|
|
|
- z-index: -1;
|
|
|
- border-left: 0.02rem solid #5ea0f7;
|
|
|
- border-top: 0.02rem solid #5ea0f7;
|
|
|
- }
|
|
|
-
|
|
|
- .service {
|
|
|
- width: 100%;
|
|
|
- color: #555;
|
|
|
- font-size: 0.28rem;
|
|
|
- padding-top: 1rem;
|
|
|
- background: #f5f5f5;
|
|
|
- }
|
|
|
-
|
|
|
- .header {
|
|
|
- position: fixed;
|
|
|
- left: 0;
|
|
|
- top: 0;
|
|
|
- width: 100%;
|
|
|
- z-index: 999;
|
|
|
- height: 1rem;
|
|
|
- background: linear-gradient(
|
|
|
- 90deg,
|
|
|
- rgba(22, 84, 209, 1) 0%,
|
|
|
- rgba(9, 52, 173, 1) 100%
|
|
|
- );
|
|
|
- box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
|
|
|
- font-size: 0.34rem;
|
|
|
- color: #fff;
|
|
|
- padding: 0 0.3rem;
|
|
|
- }
|
|
|
-
|
|
|
- .main {
|
|
|
- position: relative;
|
|
|
- box-sizing: border-box;
|
|
|
- height: 83vh;
|
|
|
- overflow-x: hidden;
|
|
|
- overflow-y: auto;
|
|
|
- padding:0.4rem 0.3rem;
|
|
|
- padding-top:0;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- .btn {
|
|
|
- display: inline-block;
|
|
|
- padding: 0 0.36rem;
|
|
|
- text-align: center;
|
|
|
- line-height: 0.4rem;
|
|
|
- background: rgba(221, 221, 221, 1);
|
|
|
- border-radius: 0.3rem;
|
|
|
- color: #fff;
|
|
|
- font-size: 0.24rem;
|
|
|
- max-width: 6rem;
|
|
|
- margin: 0 auto;
|
|
|
- margin-top: 0.3rem;
|
|
|
- }
|
|
|
-
|
|
|
- .btn .click {
|
|
|
- color: #5ea0f7;
|
|
|
- }
|
|
|
-
|
|
|
- .btnRouter {
|
|
|
- color: #5ea0f7;
|
|
|
- }
|
|
|
-
|
|
|
- .systemDialogue {
|
|
|
- min-height: 0.8rem;
|
|
|
- width: 100%;
|
|
|
- }
|
|
|
-
|
|
|
- .manUserDialogue {
|
|
|
- min-height: 1rem;
|
|
|
- }
|
|
|
-
|
|
|
- .manPlatformDialogue {
|
|
|
- min-height: 1rem;
|
|
|
- }
|
|
|
-
|
|
|
- .user {
|
|
|
- padding: 0.2rem;
|
|
|
- display: inline-block;
|
|
|
- border-radius: 0.1rem;
|
|
|
- font-size: 0.28rem;
|
|
|
- color: #fff;
|
|
|
- max-width: 19.1rem;
|
|
|
- table-layout:fixed;
|
|
|
- word-break: break-all;
|
|
|
- text-align: left;
|
|
|
- }
|
|
|
-
|
|
|
- .HeadPortrait {
|
|
|
- width: 1rem;
|
|
|
- height: 1rem;
|
|
|
- /* background: #ddd; */
|
|
|
- border-radius: 0.1rem;
|
|
|
- }
|
|
|
-
|
|
|
- .HeadPortrait img {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
-
|
|
|
- .icon {
|
|
|
- width: 0.32rem;
|
|
|
- height: 0.32rem;
|
|
|
- }
|
|
|
-
|
|
|
- .icon-msg {
|
|
|
- margin-top: 0.06rem;
|
|
|
- margin-left: 0.2rem;
|
|
|
- width: 0.32rem;
|
|
|
- height: 0.32rem;
|
|
|
- }
|
|
|
-
|
|
|
- .customerService {
|
|
|
- background: #ffffff;
|
|
|
- padding: 0.2rem;
|
|
|
- display: inline-block;
|
|
|
- border-radius: 0.1rem;
|
|
|
- font-size: 0.28rem;
|
|
|
- border: 1px solid rgba(223, 223, 223, 1);
|
|
|
- }
|
|
|
-
|
|
|
- .customerService {
|
|
|
- /* min-height: 1rem; */
|
|
|
- }
|
|
|
-
|
|
|
- .system {
|
|
|
- width: 100%;
|
|
|
- border: 0.01rem solid rgba(223, 223, 223, 1);
|
|
|
- border-radius: 0.1rem;
|
|
|
- }
|
|
|
-
|
|
|
- div /deep/ .yd-accordion-head {
|
|
|
- /* border-radius: 0.1rem; */
|
|
|
- border-bottom: 0.01rem solid rgb(238, 238, 238);
|
|
|
- padding: 0 0.2rem;
|
|
|
- }
|
|
|
-
|
|
|
- div /deep/ .yd-accordion-title, div /deep/ .yd-accordion-head-arrow {
|
|
|
- min-height: 0.8rem !important;
|
|
|
- }
|
|
|
-
|
|
|
- div /deep/ .yd-textarea textarea {
|
|
|
- -webkit-user-select: auto;
|
|
|
- }
|
|
|
-
|
|
|
- .footer {
|
|
|
- display: flex;
|
|
|
- min-height: 1.2rem;
|
|
|
- box-shadow: 0px -5px 5px rgba(0, 0, 0, 0.05);
|
|
|
- background: #fff;
|
|
|
- width: 100%;
|
|
|
- position: fixed;
|
|
|
- bottom: 0;
|
|
|
- left: 0;
|
|
|
- z-index: 1000;
|
|
|
- }
|
|
|
-
|
|
|
- .input {
|
|
|
- width: 60%;
|
|
|
- min-height: 1.2rem;
|
|
|
- padding-top: 0.4rem;
|
|
|
- padding-bottom: 0.4rem;
|
|
|
- border: none;
|
|
|
- padding-right: 0.3rem;
|
|
|
- padding-left: 0.3rem;
|
|
|
- font-size: 0.28rem;
|
|
|
- }
|
|
|
-
|
|
|
- .send {
|
|
|
- flex: 0 0 130px;
|
|
|
- margin-right: 10px;
|
|
|
- text-align: right;
|
|
|
- /* position: absolute;
|
|
|
- right: 0;
|
|
|
- top: 0; */
|
|
|
- background: #fff;
|
|
|
- height: 1.2rem;
|
|
|
- }
|
|
|
-
|
|
|
- .memeBox {
|
|
|
- height: 3rem;
|
|
|
- width: 100%;
|
|
|
- }
|
|
|
-
|
|
|
- .send img {
|
|
|
- vertical-align: middle;
|
|
|
- margin-right: 0.4rem;
|
|
|
- }
|
|
|
-
|
|
|
- .artificial {
|
|
|
- margin: 0.3rem 0 0 1.3rem;
|
|
|
- width: 77%;
|
|
|
- border: 0.01rem solid #dfdfdf;
|
|
|
- background: #fff;
|
|
|
- border-radius: 0.1rem;
|
|
|
- padding: 0 0.2rem;
|
|
|
- }
|
|
|
-
|
|
|
- div /deep/ .yd-accordion-head-arrow:after {
|
|
|
- border: none;
|
|
|
- width: 0.3rem;
|
|
|
- height: 0.3rem;
|
|
|
- background: url("../assets/addright.png") no-repeat;
|
|
|
- background-size: 100% 100%;
|
|
|
- transform: rotate(0deg);
|
|
|
- }
|
|
|
-
|
|
|
- div /deep/ .yd-accordion-head-arrow.yd-accordion-rotated:after {
|
|
|
- transform: rotate(-270deg);
|
|
|
- }
|
|
|
-
|
|
|
- div /deep/ .yd-accordion {
|
|
|
- border-radius: 0.1rem;
|
|
|
- }
|
|
|
-
|
|
|
- div /deep/ .yd-accordion-content {
|
|
|
- border-radius: 0.1rem;
|
|
|
- }
|
|
|
-
|
|
|
- .imgSrc img {
|
|
|
- width: 1.2rem;
|
|
|
- }
|
|
|
-
|
|
|
- .leftHader {
|
|
|
- height: 1rem;
|
|
|
- background: linear-gradient(
|
|
|
- 90deg,
|
|
|
- rgba(22, 84, 209, 1) 0%,
|
|
|
- rgba(9, 52, 173, 1) 100%
|
|
|
- );
|
|
|
- box-shadow: 0 0.03rem 0.03rem rgba(0, 0, 0, 0.2);
|
|
|
- padding: 0 0.3rem;
|
|
|
- }
|
|
|
-
|
|
|
- .leftMain-top {
|
|
|
- margin-top: 0.4rem;
|
|
|
- font-size: 0.28rem;
|
|
|
- line-height: 0.45rem;
|
|
|
- padding: 0 0.3rem;
|
|
|
- color: #666;
|
|
|
- }
|
|
|
-
|
|
|
- .leftMain-top span {
|
|
|
- color: #999;
|
|
|
- }
|
|
|
-
|
|
|
- .leftMain-top > div {
|
|
|
- width: 50%;
|
|
|
- }
|
|
|
-
|
|
|
- .leftMain-center {
|
|
|
- margin-top: 0.3rem;
|
|
|
- color: #666;
|
|
|
- line-height: 0.5rem;
|
|
|
- }
|
|
|
-
|
|
|
- .leftMain-chenter span {
|
|
|
- color: #999;
|
|
|
- font-size: 0.28rem;
|
|
|
- }
|
|
|
-
|
|
|
- .evaluate {
|
|
|
- height: 1.7rem;
|
|
|
- background: #fff;
|
|
|
- border: 0.01rem solid #ddd;
|
|
|
- border-radius: 0.1rem;
|
|
|
- color: #666;
|
|
|
- margin-top: 0.3rem;
|
|
|
- }
|
|
|
-
|
|
|
- .evaluateBtn {
|
|
|
- width: 1.4rem;
|
|
|
- height: 0.6rem;
|
|
|
- border: none;
|
|
|
- background: #f04992;
|
|
|
- color: #fff;
|
|
|
- border-radius: 0.1rem;
|
|
|
- }
|
|
|
-
|
|
|
- div /deep/ .yd-popup {
|
|
|
- border-radius: 0.2rem 0.2rem 0 0;
|
|
|
- }
|
|
|
-
|
|
|
- div /deep/ .yd-popup-content {
|
|
|
- }
|
|
|
-
|
|
|
- .evaluatebtn > div p {
|
|
|
- height: 50%;
|
|
|
- width: 100%;
|
|
|
- text-align: center;
|
|
|
- margin-top: 0.14rem;
|
|
|
- }
|
|
|
-
|
|
|
- .evaluatebtn > div {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- }
|
|
|
-
|
|
|
- .evaluateBox {
|
|
|
- margin: 0 0.2rem;
|
|
|
- height: 1.5rem;
|
|
|
- border: 0.01rem solid #ddd;
|
|
|
- border-radius: 0.1rem;
|
|
|
- background: #f5f5f5;
|
|
|
- }
|
|
|
-
|
|
|
- .evaluateBox textarea {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- background: #f5f5f5;
|
|
|
- border: none;
|
|
|
- border-radius: 0.1rem;
|
|
|
- padding: 0.2rem;
|
|
|
- color: #999;
|
|
|
- font-size: 0.28rem;
|
|
|
- }
|
|
|
-
|
|
|
- .sub {
|
|
|
- margin: 0 0.2rem;
|
|
|
- background: linear-gradient(
|
|
|
- 90deg,
|
|
|
- rgba(22, 84, 209, 1) 0%,
|
|
|
- rgba(9, 52, 173, 1) 100%
|
|
|
- );
|
|
|
- box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
|
|
|
- height: 1rem;
|
|
|
- font-size: 0.34rem;
|
|
|
- color: #fff;
|
|
|
- border-radius: 0.1rem;
|
|
|
- margin-top: 0.4rem;
|
|
|
- }
|
|
|
-
|
|
|
- div /deep/ .yd-popup-content {
|
|
|
- background: #fff;
|
|
|
- border-radius: 0.1rem;
|
|
|
- }
|
|
|
-
|
|
|
- .loginInput {
|
|
|
- height: 0.8rem;
|
|
|
- border: 0.01rem solid #ddd;
|
|
|
- background: #f5f5f5;
|
|
|
- border-radius: 0.1rem;
|
|
|
- margin-top: 0.5rem;
|
|
|
- padding: 0.2rem;
|
|
|
- font-size: 0.28rem;
|
|
|
- margin: 0.2rem;
|
|
|
- margin-top: 0.5rem;
|
|
|
- width: 94%;
|
|
|
- color: #999;
|
|
|
- }
|
|
|
-
|
|
|
- /* 留言 */
|
|
|
- .leave-header {
|
|
|
- height: 1rem;
|
|
|
- background: linear-gradient(
|
|
|
- 90deg,
|
|
|
- rgba(22, 84, 209, 1) 0%,
|
|
|
- rgba(9, 52, 173, 1) 100%
|
|
|
- );
|
|
|
- box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
|
|
|
- color: #fff;
|
|
|
- font-size: 0.34rem;
|
|
|
- padding: 0 0.3rem;
|
|
|
- }
|
|
|
-
|
|
|
- .leave-main {
|
|
|
- height: 10rem;
|
|
|
- background: #f5f5f5;
|
|
|
- font-size: 0.28rem;
|
|
|
- padding: 0.3rem 0.3rem 0.2rem 0.3rem;
|
|
|
- }
|
|
|
-
|
|
|
- .leave-main > div {
|
|
|
- height: 1.3rem;
|
|
|
- margin-bottom: 0.2rem;
|
|
|
- }
|
|
|
-
|
|
|
- .leave-main > div input {
|
|
|
- height: 0.8rem;
|
|
|
- border: 0.01rem solid #ddd;
|
|
|
- border-radius: 0.1rem;
|
|
|
- background: #fff;
|
|
|
- padding: 0.2rem;
|
|
|
- width: 100%;
|
|
|
- margin-top: 0.1rem;
|
|
|
- }
|
|
|
-
|
|
|
- .leave-main-txt {
|
|
|
- background: #fff;
|
|
|
- padding: 0.2rem;
|
|
|
- border: 0.01rem solid #ddd;
|
|
|
- border-radius: 0.1rem;
|
|
|
- }
|
|
|
-
|
|
|
- .imgMsg {
|
|
|
- height: 1.5rem;
|
|
|
- padding: 0 0.2rem;
|
|
|
- margin-top: 0.1rem;
|
|
|
- font-size: 0.24rem;
|
|
|
- background: #fff;
|
|
|
- border: 0.01rem solid #ddd;
|
|
|
- border-radius: 0.1rem;
|
|
|
- }
|
|
|
-
|
|
|
- .yd-cell-box {
|
|
|
- width: 60%;
|
|
|
- min-height: 1.2rem;
|
|
|
-
|
|
|
- border: none;
|
|
|
- padding-right: 0.3rem;
|
|
|
- padding-left: 0.3rem;
|
|
|
- border-bottom: 0.01rem solid rgb(221, 221, 221);
|
|
|
- }
|
|
|
-
|
|
|
- div /deep/ .yd-textarea > textarea {
|
|
|
- min-height: 1.2rem;
|
|
|
- font-size: 0.28rem;
|
|
|
- padding-top: 0.2rem;
|
|
|
- }
|
|
|
-
|
|
|
- .yd-textarea {
|
|
|
- padding: 0;
|
|
|
- }
|
|
|
-
|
|
|
- .yd-cell-box {
|
|
|
- margin: 0;
|
|
|
- }
|
|
|
-
|
|
|
- .yd-cell-item {
|
|
|
- padding: 0;
|
|
|
- }
|
|
|
-
|
|
|
- div /deep/ .yd-cell:after {
|
|
|
- height: 0;
|
|
|
- }
|
|
|
-
|
|
|
- div /deep/ .yd-textarea-counter {
|
|
|
- display: none;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- .promptBox {
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- height: 26px;
|
|
|
- margin: 10px 0 10px;
|
|
|
- /* line-height: 26px; */
|
|
|
- }
|
|
|
-
|
|
|
- .promptBoxH {
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- height: 50px;
|
|
|
- margin: 10px 0 10px;
|
|
|
- /* line-height: 26px; */
|
|
|
- }
|
|
|
-
|
|
|
- .prompt {
|
|
|
- line-height: 25px;
|
|
|
- text-align: center;
|
|
|
- background: #DDDDDD;
|
|
|
- border-radius: 30px;
|
|
|
- width: 140px;
|
|
|
- color: #FFFFFF;
|
|
|
- font-size: 12px;
|
|
|
- }
|
|
|
-
|
|
|
- .help {
|
|
|
- width: 80%;
|
|
|
- }
|
|
|
-
|
|
|
- .help .prompt {
|
|
|
- width: 100%;
|
|
|
- }
|
|
|
-
|
|
|
- .row .rightAlignment {
|
|
|
- text-align: right;
|
|
|
- display: block;
|
|
|
- }
|
|
|
- #main{
|
|
|
- /* margin-bottom: .3rem; */
|
|
|
- }
|
|
|
- /*
|
|
|
- *留言知识库
|
|
|
- */
|
|
|
-
|
|
|
-</style>
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <!-- 聊天 -->
|
|
|
+ <div class="service" v-if="!knowledge">
|
|
|
+ <!-- 头部信息 -->
|
|
|
+ <div class="header row allAlignment item-center">
|
|
|
+
|
|
|
+ <div class="row item-center" v-if="!link_success">
|
|
|
+ <img class="icon" style="margin-right:.2rem;" src="@/assets/Service1.png" @click="leftShow = true">
|
|
|
+ <img class="logo" :src="img_http + logo" alt="">
|
|
|
+ <p>{{service_info.name}}</p>
|
|
|
+ <span style="margin:5px 0 0 5px"><img src="@/assets/on_icon.png" alt=""></span>
|
|
|
+ </div>
|
|
|
+ <div class="row item-center" v-else>
|
|
|
+ <img class="icon" style="margin-right:.2rem;" src="@/assets/Service1.png" @click="leftShow = true">
|
|
|
+ <img class="logo" :src="img_http + logo" alt="">
|
|
|
+ <p>{{service_info.name}}</p>
|
|
|
+ <span v-if="service_on" style="margin:5px 0 0 5px"><img src="@/assets/on_icon.png" alt=""></span>
|
|
|
+ <span v-if="!service_on" style="margin:5px 0 0 5px"><img src="@/assets/off_icon.png" alt=""></span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="row">
|
|
|
+ <yd-button v-if="isExit" color="#fff" bgcolor="#1d57dd" class="exit" size="mini" type="primary"
|
|
|
+ @click.native="is_exit()">结束聊天
|
|
|
+ </yd-button>
|
|
|
+ <img class="icon-msg" v-if="( chat.length -1 ) + hisLength >= chatNum" @click="is_show_evaluate()" src="@/assets/Service2.png">
|
|
|
+ <img class="icon-msg" @click="knowledge = true,flag = false" src="@/assets/leaveSwitch.png" v-if="!isExit">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="main" id="main" @scroll="scrollMain">
|
|
|
+
|
|
|
+ <!-- ********************************************************** -->
|
|
|
+ <!-- 机器人聊天板块 -->
|
|
|
+ <div v-if="!link_success">
|
|
|
+ <!-- 系统欢迎语 -->
|
|
|
+ <div v-if="welcome.length > 0" v-for="(item,i) in welcome" :key="'w'+i">
|
|
|
+ <div class="row allAlignment" style="margin-top:.3rem;">
|
|
|
+ <div class="HeadPortrait row center">
|
|
|
+ <img :src="require('@/assets/headAdvent.png')">
|
|
|
+ </div>
|
|
|
+ <div class="messageWindow dialogueA col-w">
|
|
|
+ <div class="customerService left" v-html="item"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 系统消息下拉选择 -->
|
|
|
+ <div class="artificial" v-if="problem.length > 0 && welcome.length > 0">
|
|
|
+ <div class="row item-center allAlignment" style="height:.75rem;border-bottom:.01rem solid #EEE;"
|
|
|
+ v-for="(item,index) in problem" :key="index" @click="pushMessage(item.robot_content)">
|
|
|
+ <span>{{item.robot_name}}</span>
|
|
|
+ <img style="width:.3rem;height:.3rem;" src="@/assets/addright.png">
|
|
|
+ </div>
|
|
|
+ <div class="row item-center" style="height:.72rem;">
|
|
|
+ <p>以上问题都不是</p>
|
|
|
+ <div style="color:#5EA0F7;padding-left:.1rem;" @click="connectionService">转人工客服</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 和机器人会话 -->
|
|
|
+ <div v-for="(item,i) in robot" :key="'r'+i">
|
|
|
+ <!-- 和机器人会话互动 -->
|
|
|
+ <div v-if="item.type == 'error'" class="row allAlignment"
|
|
|
+ style="margin-top:.3rem;">
|
|
|
+ <div class="HeadPortrait row center">
|
|
|
+ <img v-if="item.type == 'error'" :src="require('@/assets/headAdvent.png')">
|
|
|
+ </div>
|
|
|
+ <div class="messageWindow dialogueA col-w">
|
|
|
+ <!-- <div v-if="item.type == '1001'" class="customerService left"
|
|
|
+ v-html="item.content.text"></div> -->
|
|
|
+ <!-- <div v-if="item.type == 'user'" class="user right imgSrc">
|
|
|
+ <yd-lightbox v-if="item.content.img" style="display:inline-block"
|
|
|
+ class="row rightAlignment box-img">
|
|
|
+ <yd-lightbox-img :src=" img_http + item.content.img"></yd-lightbox-img>
|
|
|
+ </yd-lightbox> -->
|
|
|
+ <div v-if="item.type == 'error'" class="customerService left">{{item.content.text}}
|
|
|
+ <div style="color:#5EA0F7;padding-left:.1rem;cursor:pointer;" @click="connectionService">转人工客服</div>
|
|
|
+ </div>
|
|
|
+ <!-- </div> -->
|
|
|
+ </div>
|
|
|
+ <div class="HeadPortrait row center">
|
|
|
+ <img v-if="item.type == 'user'"
|
|
|
+ :src="require('@/assets/timg.jpg') ">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+
|
|
|
+ <!-- 和机器人会话互动 -->
|
|
|
+ <div v-if="item.type == 'service' || item.type == 'user'" class="row allAlignment"
|
|
|
+ style="margin-top:.3rem;">
|
|
|
+ <div class="HeadPortrait row center">
|
|
|
+ <img v-if="item.type == 'service'" :src="require('@/assets/headAdvent.png')">
|
|
|
+ </div>
|
|
|
+ <div class="messageWindow dialogueA col-w"
|
|
|
+ :style="item.type == 'user'?'text-align: right;':''">
|
|
|
+ <div v-if="item.type == 'service'" class="customerService left"
|
|
|
+ v-html="item.content.text"></div>
|
|
|
+ <div v-if="item.type == 'user'" class="user right imgSrc">
|
|
|
+ <yd-lightbox v-if="item.content.img" style="display:inline-block"
|
|
|
+ class="row rightAlignment box-img">
|
|
|
+ <yd-lightbox-img :src=" img_http + item.content.img"></yd-lightbox-img>
|
|
|
+ </yd-lightbox>
|
|
|
+ <div v-else v-html="item.content"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="HeadPortrait row center">
|
|
|
+ <img v-if="item.type == 'user'"
|
|
|
+ :src="require('@/assets/timg.jpg') ">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 转人工分组 -->
|
|
|
+ <div class="artificial" v-if="item.type == 'artificial_service' ">
|
|
|
+ <div @click="turnArtificial(items.id)" v-for="(items,indexs) in item.content"
|
|
|
+ :key="'r'+indexs" class="row item-center allAlignment"
|
|
|
+ style="height:.75rem;border-bottom:.01rem solid #EEE;">
|
|
|
+ <p>
|
|
|
+ 人工客服:
|
|
|
+ <span style="color:#5EA0F7;padding-left:.1rem;">{{items.name}}</span>
|
|
|
+ </p>
|
|
|
+ <img style="width:.3rem;height:.3rem;" src="@/assets/addright.png">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- ********************************************************** -->
|
|
|
+ <!-- 人工会话模版 -->
|
|
|
+ <div v-if="link_success">
|
|
|
+ <!--历史消息-->
|
|
|
+ <div v-if="showHistory" v-for="(item, index) in hisSviceChat" :key="'h'+index">
|
|
|
+ <!-- 客服信息 -->
|
|
|
+ <div v-if="item.from_id.startsWith('KF')">
|
|
|
+ <div style="width: 100%;text-align: center;">
|
|
|
+ <span v-if="item.time_line">{{item.time_line}}</span>
|
|
|
+ </div>
|
|
|
+ <div class="row allAlignment" style="margin-top:.3rem;margin-top: 0.3rem;">
|
|
|
+ <div class="HeadPortrait row center">
|
|
|
+ <img v-if="service_info.avatar == '' " :src="avatar_imgs">
|
|
|
+ <img v-if="service_info.avatar != ''"
|
|
|
+ :src="img_http + service_info.avatar ? img_http + service_info.avatar : require('@/assets/user2.png')">
|
|
|
+ </div>
|
|
|
+ <div class="messageWindow dialogueA col-w">
|
|
|
+ <div class="customerService left imgSrc">
|
|
|
+ <yd-lightbox v-if="item.content.img" style="display:inline-block"
|
|
|
+ class="row rightAlignment">
|
|
|
+ <yd-lightbox-img :src=" img_http + item.content.img"></yd-lightbox-img>
|
|
|
+ </yd-lightbox>
|
|
|
+ <div v-html="item.content.text" v-else></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="HeadPortrait row center">
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 用户信息 -->
|
|
|
+ <div v-else>
|
|
|
+ <div style="width: 100%;text-align: center;margin-top: 0.3rem;">
|
|
|
+ <span v-if="item.time_line">{{item.time_line}}</span>
|
|
|
+ </div>
|
|
|
+ <div class="row allAlignment" style="margin-top:.3rem;">
|
|
|
+ <div class="HeadPortrait row center">
|
|
|
+
|
|
|
+ </div>
|
|
|
+ <div class="messageWindow dialogueA col-w row rightAlignment" >
|
|
|
+ <div class="user right imgSrc ">
|
|
|
+ <yd-lightbox v-if="item.content.img" style="display:inline-block" class="row rightAlignment">
|
|
|
+ <yd-lightbox-img :src="img_http+item.content.img"></yd-lightbox-img>
|
|
|
+ </yd-lightbox>
|
|
|
+ <div v-html="item.content.text" v-else></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="HeadPortrait row center">
|
|
|
+ <img :src="require('@/assets/timg.jpg') ">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-for="(item,index) in chat" :key="index">
|
|
|
+
|
|
|
+ <!-- 展示历史消息 -->
|
|
|
+ <div class="promptBox" v-if="item.type == 'historyMsg'">
|
|
|
+ <div class="prompt help">
|
|
|
+ <span>{{historyMsgtext}}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 客服会话 -->
|
|
|
+ <div v-if="item.type == 'service'">
|
|
|
+ <div style="width: 100%;text-align: center;margin-top: 0.3rem;">
|
|
|
+ <span v-if="item.time ">{{item.time}}</span>
|
|
|
+ </div>
|
|
|
+ <div class="row allAlignment" style="margin-top:.3rem;">
|
|
|
+ <div class="HeadPortrait row center">
|
|
|
+ <img id="123" v-if="service_info.avatar == '' " :src="avatar_imgs">
|
|
|
+ <img id="321" v-if="service_info.avatar != '' "
|
|
|
+ :src="img_http + service_info.avatar ? img_http + service_info.avatar : img_http + service_info.avatar">
|
|
|
+ </div>
|
|
|
+ <div class="messageWindow dialogueA col-w ">
|
|
|
+ <div class="customerService left imgSrc">
|
|
|
+ <yd-lightbox v-if="item.content.img" style="display:inline-block"
|
|
|
+ class="row rightAlignment">
|
|
|
+ <yd-lightbox-img :src="img_http + item.content.img"></yd-lightbox-img>
|
|
|
+ </yd-lightbox>
|
|
|
+ <div v-html="item.content.text" v-else></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="HeadPortrait row center">
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 用户会话 -->
|
|
|
+ <div v-if="item.type == 'user'">
|
|
|
+ <div style="width: 100%;text-align: center;margin-top: 0.3rem;">
|
|
|
+ <span v-if="item.time">{{item.time}}</span>
|
|
|
+ </div>
|
|
|
+ <div class="row allAlignment" style="margin-top:.3rem;">
|
|
|
+ <div class="HeadPortrait row center">
|
|
|
+
|
|
|
+ </div>
|
|
|
+ <div class="messageWindow dialogueA col-w row rightAlignment" >
|
|
|
+ <div class="user right imgSrc ">
|
|
|
+ <yd-lightbox v-if="item.content.img" style="display:inline-block"
|
|
|
+ class="row rightAlignment">
|
|
|
+ <yd-lightbox-img :src="img_http+item.content.img"></yd-lightbox-img>
|
|
|
+ </yd-lightbox>
|
|
|
+ <span v-html="item.content.text" v-else>{{item.content.text}}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="HeadPortrait row center">
|
|
|
+ <img v-if="item.type == 'user'"
|
|
|
+ :src="require('@/assets/timg.jpg') ">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 常规系统消息评价 -->
|
|
|
+ <div class="row center " v-if="item.type== 'system' ">
|
|
|
+ <div class="column item-center "
|
|
|
+ style="margin: 0.3rem 0; background: #fff; width:100% ;padding: 0.1rem 0;"
|
|
|
+ v-if="item.content.state =='getEvaluate' && !haveEvaluation ">
|
|
|
+ <p class="row center wrap">{{item.content.text}}</p>
|
|
|
+ <button class="evaluateBtn" style="margin-top:.2rem;" @click="is_show_evaluate()">评价
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="column item-center"
|
|
|
+ style="margin: 0.3rem 0; background: #fff; width:100% ;padding: 0.1rem 0.5rem;"
|
|
|
+ v-if="item.content.state == 'closeInform' ">
|
|
|
+ <p class="row center wrap">{{item.content.text}}</p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-if="Chrome_height" style="height:40px">
|
|
|
+
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-if="Safari_height" style="height:90px">
|
|
|
+
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 底部弹窗评价 -->
|
|
|
+ <yd-popup v-model="bottomShow" position="bottom" height="6.5rem" :masker-opacity=".2">
|
|
|
+ <div class="row rightAlignment" style="padding-top:.2rem;padding-right:.2rem;">
|
|
|
+ <img @click.stop="bottomShow = false, evaluateState = 100" style="width: 0.32rem;height: 0.32rem;"
|
|
|
+ src="@/assets/Service5.png">
|
|
|
+ </div>
|
|
|
+ <div style="color:#666;text-align: center;font-size:.28rem;">感谢您的咨询,请对我们的服务做出评价</div>
|
|
|
+ <div style="height:2.3rem;" class="row allAlignment evaluatebtn">
|
|
|
+ <div style="width:33%;height:100%;">
|
|
|
+ <div class="row wrap center" @click="evaluateClick(1)">
|
|
|
+ <img style="width:.66rem;height:.66rem;"
|
|
|
+ :src="evaluateState =='1'?require('@/assets/evaluate1a.png'):require('@/assets/evaluate1.png')">
|
|
|
+ <p>满意</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div style="width:33%;height:100%;" @click="evaluateClick(2)">
|
|
|
+ <div class="row wrap center">
|
|
|
+ <img style="width:.66rem;height:.66rem;"
|
|
|
+ :src="evaluateState =='2'?require('@/assets/evaluate2a.png'):require('@/assets/evaluate2.png')">
|
|
|
+ <p>一般</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div style="width:33%;height:100%;" @click="evaluateClick(3)">
|
|
|
+ <div class="row wrap center">
|
|
|
+ <img style="width:.66rem;height:.66rem;"
|
|
|
+ :src="evaluateState =='3'?require('@/assets/evaluate3a.png'):require('@/assets/evaluate3.png')">
|
|
|
+ <p>不满意</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- <div class="evaluateBox">
|
|
|
+ <textarea placeholder="评价备注" v-model="evalArea"></textarea>
|
|
|
+ </div> -->
|
|
|
+ <div class="row center sub" @click="evaluateEsc">确定</div>
|
|
|
+ </yd-popup>
|
|
|
+
|
|
|
+ <!-- 左侧弹窗客服信息 -->
|
|
|
+ <yd-popup v-model="leftShow" position="left" width="4.8rem" :masker-opacity=".2">
|
|
|
+ <div class="leftHader row item-center">
|
|
|
+ <img @click="leftShow = false" class="icon" src="@/assets/Service4.png">
|
|
|
+ <img class="logo" :src="img_http + logo" alt="">
|
|
|
+ <p style="color:#FFF;font-size:.34rem;">{{service_info.name}}</p>
|
|
|
+
|
|
|
+
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <div class="leftMain-top row">
|
|
|
+ <div>
|
|
|
+ <p>
|
|
|
+ <!-- 客服名字 -->
|
|
|
+ <span>姓名:</span>
|
|
|
+ {{service_info.name}}
|
|
|
+ </p>
|
|
|
+ <p>
|
|
|
+ <!-- 客服工号 -->
|
|
|
+ <span>工号:</span>
|
|
|
+ {{service_info.job_name}}
|
|
|
+ </p>
|
|
|
+ <p>
|
|
|
+ <!-- 客服性别 -->
|
|
|
+ <span>性别:</span>
|
|
|
+ {{service_info.gender == "0" ? "保密" :service_info.gender == 1? '男' :'女' }}
|
|
|
+ </p>
|
|
|
+ <p>
|
|
|
+ <!-- 客服职务 -->
|
|
|
+ <span>职务:</span>
|
|
|
+ {{service_info.job_name}}
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ <div class="row center">
|
|
|
+ <img style="width:1.8rem;height:1.8rem;" v-if="!trueImg" :src="avatar_imgs">
|
|
|
+ <!-- {{service_info.avatar}} -->
|
|
|
+ <img style="width:1.8rem;height:1.8rem;" v-if="trueImg" :src="img_http +service_info.avatar">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="leftMain-chenter"
|
|
|
+ style="padding:0 .3rem;margin-top:.3rem;padding-bottom:.6rem;border-bottom:.01rem solid #ddd;"
|
|
|
+ >
|
|
|
+ <!-- 客服个性签名 -->
|
|
|
+ <span>个性签名:</span>
|
|
|
+ {{service_info.signature}}
|
|
|
+ </div>
|
|
|
+ <!-- 广告图 -->
|
|
|
+ <div class="leftMain-bottom row center" style="padding:0 .3rem;margin-top:.6rem;">
|
|
|
+ <a :href="'https://'+advertisement.advertisement_url" target="_blank" rel="noopener noreferrer">
|
|
|
+ <img style="width:4.2rem;height:7rem;" :src="img_http+advertisement.advertisement_img">
|
|
|
+ </a>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </yd-popup>
|
|
|
+ <!-- 底部输入框 -->
|
|
|
+ <div class="footer row wrap" id='input_box'>
|
|
|
+ <!-- @keydown="inputNumFun()" -->
|
|
|
+ <textarea
|
|
|
+ id="textarea"
|
|
|
+ v-model.trim="text_info"
|
|
|
+ placeholder="请输入你的问题:"
|
|
|
+ maxlength="450"
|
|
|
+ @keyup ='keyup_maxlength()'
|
|
|
+ @focus="keyup_maxlength()"
|
|
|
+ :style="{height:iboxheight}"
|
|
|
+ >
|
|
|
+ </textarea>
|
|
|
+ <div class="send row item-center" style="border-bottom:.01rem solid #ddd;">
|
|
|
+ <img
|
|
|
+ :src="meme?require('@/assets/faceActive.png'):require('@/assets/face.png')"
|
|
|
+ @click="faceClick"
|
|
|
+ style="width:.48rem;height:.48rem"
|
|
|
+ >
|
|
|
+ <input type="file" id="file" @change="uploadIMG" accept="image/jpeg,image/jpg,image/png,image/svg"
|
|
|
+ style="display:none">
|
|
|
+ <label for="file">
|
|
|
+ <img src="@/assets/imge.png" style="width:.46rem;height:.42rem">
|
|
|
+ </label>
|
|
|
+ <div
|
|
|
+ @click="send()"
|
|
|
+ style="color:#ccc;border:.02rem solid #ddd;width:1rem;height:.66rem;border-radius:.1rem;"
|
|
|
+ :style="text_info.length>0?'background:#5EA0F7;color:#fff;':''"
|
|
|
+ class="row center"
|
|
|
+ >发送
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 表情包 -->
|
|
|
+ <div v-show="meme" class="memeBox">
|
|
|
+ <yd-slider autoplay="0" :loop="false">
|
|
|
+ <yd-slider-item>
|
|
|
+ <div>
|
|
|
+ <ul style="width:100%;padding-bottom:.3rem;" class="row average wrap">
|
|
|
+ <li v-for="(item,index) in frceArr" :key="index" v-show="index<15">
|
|
|
+ <img
|
|
|
+ class="memeImg"
|
|
|
+ :src="require(`@/assets/${index}.gif`)"
|
|
|
+ @click="memeImg(index)"
|
|
|
+ >
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </yd-slider-item>
|
|
|
+ <yd-slider-item>
|
|
|
+ <div>
|
|
|
+ <ul style="width:100%;padding-bottom:.3rem;" class="row average wrap">
|
|
|
+ <li v-for="(item,index) in frceArr" :key="index" v-show="index>15&&index<=30">
|
|
|
+ <img
|
|
|
+ class="memeImg"
|
|
|
+ :src="require(`@/assets/${index}.gif`)"
|
|
|
+ @click="memeImg(index)"
|
|
|
+ >
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </yd-slider-item>
|
|
|
+ <yd-slider-item>
|
|
|
+ <div>
|
|
|
+ <ul style="width:100%;padding-bottom:.3rem;" class="row average wrap">
|
|
|
+ <li v-for="(item,index) in frceArr" :key="index" v-show="index>30&&index<=45">
|
|
|
+ <img
|
|
|
+ class="memeImg"
|
|
|
+ :src="require(`@/assets/${index}.gif`)"
|
|
|
+ @click="memeImg(index)"
|
|
|
+ >
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </yd-slider-item>
|
|
|
+ <yd-slider-item>
|
|
|
+ <div>
|
|
|
+ <ul style="width:100%;padding-bottom:.3rem;" class="row average wrap">
|
|
|
+ <li v-for="(item,index) in frceArr" :key="index" v-show="index>45&&index<=60">
|
|
|
+ <img
|
|
|
+ class="memeImg"
|
|
|
+ :src="require(`@/assets/${index}.gif`)"
|
|
|
+ @click="memeImg(index)"
|
|
|
+ >
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </yd-slider-item>
|
|
|
+ <yd-slider-item>
|
|
|
+ <div>
|
|
|
+ <ul style="width:100%;padding-bottom:.3rem;" class="row average wrap">
|
|
|
+ <li v-for="(item,index) in frceArr" :key="index" v-show="index>60">
|
|
|
+ <img
|
|
|
+ class="memeImg"
|
|
|
+ :src="require(`@/assets/${index}.gif`)"
|
|
|
+ @click="memeImg(index)"
|
|
|
+ >
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </yd-slider-item>
|
|
|
+ </yd-slider>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 留言知识库 -->
|
|
|
+ <div v-if="knowledge">
|
|
|
+ <!-- 接收返回消息 -->
|
|
|
+ <knowledgeLibrary @returnIndex="returnIndex" :currentTime="currentTime"/>
|
|
|
+ </div>
|
|
|
+ <!-- 发送消息音频提示
|
|
|
+ <audio id="send" src="../../static/send.wav"></audio>
|
|
|
+ 接收消息音频提示
|
|
|
+ <audio id="receive" src="../../static/receive.wav"></audio>
|
|
|
+ -->
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import "../css/index.css";
|
|
|
+ import knowledgeLibrary from './knowledgeLibrary'
|
|
|
+ import frce from "./frce.js";
|
|
|
+ import defaultImgs from "./../assets/timg.jpg"
|
|
|
+ import headPortrait from "./../assets/headPortrait.png"
|
|
|
+ import autoTextarea from 'auto-textarea'
|
|
|
+ import { Loading } from 'vue-ydui/dist/lib.rem/dialog';
|
|
|
+ export default {
|
|
|
+ name: "service",
|
|
|
+ // 模板注册
|
|
|
+ components: {
|
|
|
+ knowledgeLibrary,
|
|
|
+ autoTextarea
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ /*-----------------------------------------------*/
|
|
|
+ text_info: "", //输入框内容
|
|
|
+ knowledge: false,//留言知识库开关
|
|
|
+ leftShow: false, //左侧详细开关
|
|
|
+ evaluateOnOff: false, //人工客服评价通知
|
|
|
+ bottomShow: false, //底部评价弹窗开关
|
|
|
+ meme: false, // 表情包开关
|
|
|
+ frceArr: [], //表情包代码
|
|
|
+ evaluateState: 100,//评价状态
|
|
|
+ websock: null,//创建websock
|
|
|
+ user_info: '',//用户信息
|
|
|
+ apiToken: '',//通话调用凭证
|
|
|
+ currentTime: '',//接口调用服务器时间
|
|
|
+ problem: [],//机器人问题
|
|
|
+ welcome: [],//欢迎语
|
|
|
+ advertisement: '', //广告
|
|
|
+ img_http: 'https://manage.281570.com',//图片路径域
|
|
|
+ //img_http:'http://192.168.2.186:8090',//图片路径域
|
|
|
+
|
|
|
+ robot: [],//和机器人聊天临时数据
|
|
|
+ chat: [],//人工会话
|
|
|
+ error_num: 1001,//机器人回答超出能力之外编号
|
|
|
+ isConnection: true,//人工分组列表开关
|
|
|
+ ibox_height:'auto',
|
|
|
+ //客服信息
|
|
|
+ service_info: {
|
|
|
+ avatar: headPortrait,
|
|
|
+ job_name: '001',
|
|
|
+ name: '智能客服',
|
|
|
+ signature: ""
|
|
|
+ },
|
|
|
+ link_success: false,//人工链接成功
|
|
|
+ service_on: true,
|
|
|
+ closeByServer: false, //客服关闭会话
|
|
|
+ serverNotOnlin: false, //客服掉线
|
|
|
+ willOverTime: false, //超时关闭会话
|
|
|
+ overTimeMsg: '', // 超时提示内容
|
|
|
+ conversationId: '',//会话工单
|
|
|
+ chatNum: 0,//触发评价按钮条件
|
|
|
+ haveEvaluation: false,//是否已评价
|
|
|
+ evalArea: '', //评价备注
|
|
|
+ source: {},//来源信息
|
|
|
+ initData: 1,//
|
|
|
+ isTurnArtifcial: true,
|
|
|
+ Chrome_height: false, // chrome浏览器增加会话框高度
|
|
|
+ Safari_height:false, // 苹果浏览器增加会话框高度
|
|
|
+ logo: '',
|
|
|
+ isExit: false,
|
|
|
+ historyMsg: false, // 是否展示历史信息
|
|
|
+ historyMsgtext: "", // 历史信息内容提示
|
|
|
+ hisSviceChat: [],
|
|
|
+ showHistory: true,
|
|
|
+ avatar_imgs: headPortrait,
|
|
|
+ webTime: '',//人工会话上一次发送消息时间
|
|
|
+ chatIndex: '',//人工会话上一次下标
|
|
|
+ /*****************websockt心跳变量*******************/
|
|
|
+ reconnectData: null,
|
|
|
+ lockReconnect: false, //避免重复连接,因为onerror之后会立即触发 onclose
|
|
|
+ timeout: 5000, //5s一次心跳检测
|
|
|
+ timeoutObj: null,
|
|
|
+ serverTimeoutObj: null,
|
|
|
+ waitingMsg: false, // 是否显示等待排队
|
|
|
+ serviceNotOnlineText: '',
|
|
|
+ comtSuccess:false,
|
|
|
+ hisLength:0,
|
|
|
+ trueImg:false,
|
|
|
+ innerHeight: 0, // 可视区域高度,不包括键盘
|
|
|
+ areaHeight: 0, // textarea高度
|
|
|
+ loadingobj:null,//加载特效对像
|
|
|
+ };
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.getInnerHeight();
|
|
|
+ },
|
|
|
+ // 方法
|
|
|
+ methods: {
|
|
|
+ // 获取初始的可视高度
|
|
|
+ getInnerHeight() {
|
|
|
+ console.log('当前高度:', window.innerHeight)
|
|
|
+ this.innerHeight = window.innerHeight;
|
|
|
+ },
|
|
|
+ // 光标
|
|
|
+ // // 退出聊天
|
|
|
+ is_exit() {
|
|
|
+ this.webTime = ''
|
|
|
+ this.socket_send(JSON.stringify({
|
|
|
+ type: 'kfCloseUser',
|
|
|
+ data: {
|
|
|
+ to_id: this.user_info.id,
|
|
|
+ kf_id: this.service_info.id,
|
|
|
+ group_id: this.service_info.group,
|
|
|
+ conversationId: this.conversationId,
|
|
|
+ type: 6,
|
|
|
+ }
|
|
|
+ }));
|
|
|
+ this.setInit();
|
|
|
+
|
|
|
+ },
|
|
|
+ nloding(msg){
|
|
|
+ this.$dialog.loading.open(msg);
|
|
|
+ },
|
|
|
+ closeNloading(){
|
|
|
+ this.$dialog.loading.close();
|
|
|
+ },
|
|
|
+ /*******************************************/
|
|
|
+ //设置token加密
|
|
|
+ setApiToken(name, controller, time, modules) {
|
|
|
+ //let txetVal = name + 'customer-service' + controller + time + modules;
|
|
|
+ let txetVal = name + 'customer-service' + controller + modules;
|
|
|
+ let sssd = txetVal.toLowerCase();
|
|
|
+ return this.$md5(txetVal.toLowerCase());
|
|
|
+ },
|
|
|
+
|
|
|
+ /*******************************************/
|
|
|
+ //初始化Websocket链接
|
|
|
+ initWebSocket(apiToken) {
|
|
|
+ let sock_ip = ''; // 线上
|
|
|
+ this.websock = new WebSocket("wss://link.281570.com?apiToken=" + apiToken);
|
|
|
+ //数据返回
|
|
|
+ this.websock.onmessage = this.socket_message;
|
|
|
+ //数据发送
|
|
|
+ this.websock.onopen = this.socket_open;
|
|
|
+ //重新链接
|
|
|
+ this.websock.onerror = this.socket_error;
|
|
|
+ //关闭链接
|
|
|
+ this.websock.onclose = this.socket_close;
|
|
|
+ },
|
|
|
+
|
|
|
+ /*******************************************/
|
|
|
+ //连接建立之后执行send方法发送数据
|
|
|
+ socket_open() {
|
|
|
+ console.log('我链接了');
|
|
|
+ this.$dialog.loading.close();
|
|
|
+ },
|
|
|
+
|
|
|
+ /*******************************************/
|
|
|
+ //连接建立失败重连
|
|
|
+ socket_error() {
|
|
|
+ console.log('连接建立失败重连');
|
|
|
+ // this.initWebSocket();
|
|
|
+ // this.setInit();
|
|
|
+ // this.reconnect();
|
|
|
+ },
|
|
|
+
|
|
|
+ /*******************************************/
|
|
|
+ //数据接收
|
|
|
+ socket_message(e) {
|
|
|
+ if (!e.data) return;
|
|
|
+ const redata = JSON.parse(e.data);
|
|
|
+ //心跳检测
|
|
|
+ this.heatBeat();
|
|
|
+ // 心跳检测
|
|
|
+ if (redata.message_type == "ping") {
|
|
|
+ this.websock.send('{"type":"pong"}')
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (redata.type == 'pong') return false;
|
|
|
+
|
|
|
+ if (redata.type != 'pong' || redata.message_type != "ping") {
|
|
|
+ console.log(redata)
|
|
|
+ }
|
|
|
+ //欢迎语
|
|
|
+ if (redata.message_type == 'helloMessage') {
|
|
|
+ this.isTurnArtifcial = true;
|
|
|
+ if (this.initData == 1) {
|
|
|
+ this.welcome.push(redata.data.content);
|
|
|
+ //this.welcome.push('请点击您想咨询的问题,若都不是,请在输入框直接输入');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //广告语
|
|
|
+ if (redata.message_type == 'advertisement') {
|
|
|
+ this.advertisement = redata.data[0]
|
|
|
+ }
|
|
|
+
|
|
|
+ //机器人回复
|
|
|
+ if (redata.message_type == "robotMessage") {
|
|
|
+ // console.log(redata);
|
|
|
+ if (redata.data.content == "error") {
|
|
|
+ this.robot.push({
|
|
|
+ type: 'error',
|
|
|
+ content: {text: "您的问题暂无法处理"}
|
|
|
+ })
|
|
|
+ // this.error_num++;
|
|
|
+ } else {
|
|
|
+ this.robot.push({
|
|
|
+ type: 'service',
|
|
|
+ content: {text: redata.data.content}
|
|
|
+ })
|
|
|
+ }
|
|
|
+ //console.log(this.robot);
|
|
|
+ // this.automaticRolling();
|
|
|
+ //data
|
|
|
+ //this.robot =
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //人工链接
|
|
|
+ if (redata.message_type == 'connect') {
|
|
|
+ this.willOverTime = false;
|
|
|
+ this.trueImg = true
|
|
|
+ this.chat.splice(-1)
|
|
|
+ let server = {};
|
|
|
+ if (redata.data) {
|
|
|
+ server = redata.data
|
|
|
+ } else {
|
|
|
+ server = {
|
|
|
+ conversationId: redata.data.conversationId,
|
|
|
+ kf_id: redata.data.kf_id,
|
|
|
+ kf_name: "",
|
|
|
+ serverInfo: {
|
|
|
+ avatar: avatarImgs,
|
|
|
+ client_id: "",
|
|
|
+ group: "",
|
|
|
+ id: "",
|
|
|
+ intime: "",
|
|
|
+ job_name: "",
|
|
|
+ name: "tank",
|
|
|
+ signature: "",
|
|
|
+ status: 0,
|
|
|
+ task: 0,
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.service_on = true;
|
|
|
+ this.isExit = true;
|
|
|
+ this.link_success = true;
|
|
|
+ // localStorage.getItem('comtSuccess',true)
|
|
|
+ this.$dialog.loading.close();
|
|
|
+ this.service_info = server.serverInfo;
|
|
|
+ this.conversationId = server.conversationId;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 客服掉线.
|
|
|
+ if (redata.message_type == 'serviceoffline') {
|
|
|
+ this.chat.push({
|
|
|
+ type: 'system',
|
|
|
+ content: {
|
|
|
+ text: redata.msg,
|
|
|
+ state: 'closeInform',
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this.automaticRolling();
|
|
|
+ this.service_on = false;
|
|
|
+ // let that = this;
|
|
|
+ // setTimeout(function () {
|
|
|
+ // that.link_success = false;
|
|
|
+ // that.serverNotOnlin = true;
|
|
|
+ // that.closeByServer = true;
|
|
|
+ // that.chat.splice(-1)
|
|
|
+ // },3000)
|
|
|
+
|
|
|
+ }
|
|
|
+ // 客服不在线请稍后再试
|
|
|
+ if (redata.message_type == 'kfNotOnlin') {
|
|
|
+ this.service_on = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 客服会话超时
|
|
|
+ if (redata.message_type == 'overtime') {
|
|
|
+ this.willOverTime = true;
|
|
|
+ this.automaticRolling();
|
|
|
+ // this.goBack();
|
|
|
+ this.overTimeMsg = redata.data.content;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 客服等待排队
|
|
|
+ if (redata.message_type == "inqueue") {
|
|
|
+ this.waitingMsg = true;
|
|
|
+ // this.automaticRolling();
|
|
|
+ // this.waitingText = redata.content;
|
|
|
+ this.$dialog.confirm({
|
|
|
+ title: '温馨提示',
|
|
|
+ mes: redata.content,
|
|
|
+ opts: [{
|
|
|
+ txt: '取消排队',
|
|
|
+ color: true,
|
|
|
+ callback: () => {
|
|
|
+
|
|
|
+ this.socket_send(JSON.stringify({
|
|
|
+ "type": "cancelqueue",
|
|
|
+ "data": {
|
|
|
+ "uid": localStorage.getItem('uid')
|
|
|
+ }
|
|
|
+ }));
|
|
|
+ this.isTurnArtifcial =true;
|
|
|
+ // this.$dialog.toast({mes: '你点了确定', timeout: 1000});
|
|
|
+ }
|
|
|
+ }]
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ //人工会话回复
|
|
|
+ if (redata.message_type == "chatMessage") {
|
|
|
+ // 转接的时候清除历史信息
|
|
|
+ // this.hisSviceChat = [];
|
|
|
+ // this.getHistory = false;
|
|
|
+ // 接收提示音
|
|
|
+ this.receiveAudio();
|
|
|
+ this.$dialog.loading.close();
|
|
|
+ let obj = {};
|
|
|
+ let thisTime = '';
|
|
|
+ if (this.$public.isJSON(redata.data.content)) {
|
|
|
+ obj = JSON.parse(redata.data.content);
|
|
|
+ obj.text = this.turnFace(obj.text);
|
|
|
+ //接收消息大于两分钟显示时间
|
|
|
+ let newTime = redata.data.time.split(':');
|
|
|
+ if (this.webTime) {
|
|
|
+ let lastTime = this.webTime.split(":");
|
|
|
+ if (newTime[0] == lastTime[0] && newTime[1] < (lastTime[1] + 2)) {
|
|
|
+ thisTime = ''
|
|
|
+ } else {
|
|
|
+ thisTime = redata.data.time;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ thisTime = redata.data.time;
|
|
|
+ }
|
|
|
+ this.webTime = redata.data.time;
|
|
|
+ } else {
|
|
|
+ obj.text = redata.data.content;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ this.chat.push({
|
|
|
+ type: 'service',
|
|
|
+ time: thisTime ? thisTime : '',
|
|
|
+ content: obj
|
|
|
+ })
|
|
|
+ }
|
|
|
+ //系统消息通知客户结束通话
|
|
|
+ if (redata.message_type == 'closeBysever') {
|
|
|
+ this.setInit();
|
|
|
+ this.showHistory = false;
|
|
|
+ this.link_success = false;
|
|
|
+ this.isTurnArtifcial = true;
|
|
|
+ localStorage.removeItem('comtSuccess');
|
|
|
+ this.comtSuccess = false;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if (redata.message_type == "changeKeFuSuccess") {
|
|
|
+ this.$dialog.alert({
|
|
|
+ mes: redata.data.content
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //系统消息通转人工
|
|
|
+ if (redata.message_type == 'notice') {
|
|
|
+ console.log('人工');
|
|
|
+ this.$dialog.loading.close();
|
|
|
+ this.isTurnArtifcial = true;
|
|
|
+ let _this = this;
|
|
|
+ if(this.group == 99999){
|
|
|
+ this.$dialog.alert({
|
|
|
+ mes: redata.content, callback: () => {
|
|
|
+ this.initData = 100;
|
|
|
+ // _this.$dialog.loading.open('数据加载中...');
|
|
|
+ // setTimeout(() => {
|
|
|
+ // _this.$dialog.loading.close();
|
|
|
+ // // _this.registered();
|
|
|
+ // }, 2000);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }else{
|
|
|
+ this.turnArtificial(99999);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //系统消息评价
|
|
|
+ if (redata.message_type == "getEvaluate") {
|
|
|
+ // this.evaluateOnOff = true;
|
|
|
+ // console.log( this.chat)
|
|
|
+ this.chat.push({
|
|
|
+ type: 'system',
|
|
|
+ content: {
|
|
|
+ text: redata.data.content,
|
|
|
+ state: 'getEvaluate',
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ //会话关闭前通知用户
|
|
|
+ if (redata.message_type == 'overtime') {
|
|
|
+ this.chat.push({
|
|
|
+ type: 'system',
|
|
|
+ content: {
|
|
|
+ text: redata.data.content,
|
|
|
+ state: 'closeInform',
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 历史信息
|
|
|
+ if (redata.message_type == 'toOld') {
|
|
|
+ this.hisSviceChat = [];
|
|
|
+ let obj = redata;
|
|
|
+ this.historyMsgtext = obj.data.content;
|
|
|
+ this.chat.push({
|
|
|
+ type: 'historyMsg',
|
|
|
+ content: {
|
|
|
+ text: this.historyMsgtext,
|
|
|
+ }
|
|
|
+ })
|
|
|
+ let historyTime = '';
|
|
|
+ this.hisLength =obj.data.chatLog.length
|
|
|
+ obj.data.chatLog.forEach(res => {
|
|
|
+ // console.log(res,'历史信息');
|
|
|
+ res.content = JSON.parse(res.content);
|
|
|
+ res.content.text =this.turnFace(res.content.text);
|
|
|
+ let time_line = this.$public.customFormatDateTime(res.time_line, '', 3);
|
|
|
+ if (!historyTime) {
|
|
|
+ res.time_line = time_line
|
|
|
+ } else {
|
|
|
+ let newTime = time_line.split(':');
|
|
|
+ let lastTime = historyTime.split(':');
|
|
|
+ if (newTime[0] == lastTime[0] && newTime[1] < (lastTime[1] + 2)) {
|
|
|
+ res.time_line = '';
|
|
|
+ } else {
|
|
|
+ res.time_line = time_line
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // console.log(res.content);
|
|
|
+ historyTime = time_line;
|
|
|
+ this.hisSviceChat.push(res);
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取发送时间
|
|
|
+ if (redata.message_type == "webTime") {
|
|
|
+ // console.log(this.chat)
|
|
|
+ // console.log(this.chatIndex)
|
|
|
+ if (this.webTime) {
|
|
|
+ let newTime = redata.data.webTime.split(':');
|
|
|
+ let time = this.webTime.split(':');
|
|
|
+
|
|
|
+ if (newTime[0] * 1 > time[0] * 1) {
|
|
|
+ // console.log('newTime[0]')
|
|
|
+ this.$set(this.chat[this.chatIndex], 'time', redata.data.webTime);
|
|
|
+ } else if (newTime[0] * 1 == time[0] * 1 && (newTime[1] * 1 - time[1] * 1) > 2) {
|
|
|
+ this.$set(this.chat[this.chatIndex], 'time', redata.data.webTime);
|
|
|
+ // console.log('newTime[1]')
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.$set(this.chat[this.chatIndex],'time',redata.data.webTime);
|
|
|
+ }
|
|
|
+ this.webTime = redata.data.webTime
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 评价返回
|
|
|
+ if (redata.message_type == "evaluate") {
|
|
|
+ if (redata.data.status == 1) {
|
|
|
+ this.comtSuccess = true;
|
|
|
+ localStorage.setItem('comtSuccess',true)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //屏幕滚动
|
|
|
+ this.automaticRolling();
|
|
|
+ },
|
|
|
+
|
|
|
+ /*******************************************/
|
|
|
+ //数据发送
|
|
|
+ socket_send(Data) {
|
|
|
+ this.websock.send(Data);
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ /*******************************************/
|
|
|
+ //关闭
|
|
|
+ socket_close(e) {
|
|
|
+ console.log('断开连接', e);
|
|
|
+ this.nloding('网络接中...');
|
|
|
+ this.initData = 100;
|
|
|
+ this.link_success = false;
|
|
|
+ this.setInit();
|
|
|
+ this.reconnect();
|
|
|
+ // this.registered();
|
|
|
+ // this.websock.close()
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ /***************************************/
|
|
|
+ //socket重连
|
|
|
+ reconnect() {
|
|
|
+ if (this.lockReconnect) { //这里很关键,因为连接失败之后之后会相继触发 连接关闭,不然会连接上两个 WebSocket
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.lockReconnect = true;
|
|
|
+ this.reconnectData && clearTimeout(this.reconnectData);
|
|
|
+ this.reconnectData = setTimeout(() => {
|
|
|
+ this.initWebSocket(this.apiToken);
|
|
|
+ //this.registered()
|
|
|
+ // console.log('-----lail-----');
|
|
|
+ this.lockReconnect = false;
|
|
|
+ }, 2000)
|
|
|
+ },
|
|
|
+
|
|
|
+ /*************************************/
|
|
|
+ //心跳检测
|
|
|
+ heatBeat() {
|
|
|
+ this.timeoutObj && clearTimeout(this.timeoutObj);
|
|
|
+ this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
|
|
|
+ this.timeoutObj = setTimeout(() => {
|
|
|
+ // console.log('发送', {type: 'ping'});
|
|
|
+ this.socket_send(JSON.stringify({type: 'ping'})) //根据后台要求发送
|
|
|
+ this.serverTimeoutObj = setTimeout(() => {
|
|
|
+ // console.log('------close-------')
|
|
|
+ this.websock.close(); //如果 4秒之后我们没有收到 后台返回的心跳检测数据 断开socket,断开后会启动重连机制
|
|
|
+ }, 4000);
|
|
|
+ }, this.timeout)
|
|
|
+ },
|
|
|
+
|
|
|
+ /*****************************************/
|
|
|
+ //用户匿名注册
|
|
|
+ registered() {
|
|
|
+ let token = localStorage.getItem('token');
|
|
|
+ let appuid = this.$public.getQueryString('appuid');
|
|
|
+ let tutype = this.$public.getQueryString('tutype');
|
|
|
+ if (appuid && tutype >= 1) {
|
|
|
+ token = localStorage.getItem('token');
|
|
|
+ } else if (!appuid && tutype < 1) {
|
|
|
+ token = localStorage.getItem('token');
|
|
|
+ } else {
|
|
|
+ token = '';
|
|
|
+ }
|
|
|
+ let data = {
|
|
|
+ token: token != null ? token : '',
|
|
|
+ appid: this.$public.getQueryString('appid'),
|
|
|
+ appuid: this.$public.getQueryString('appuid'),
|
|
|
+ }
|
|
|
+ let obj = {
|
|
|
+ headers: {
|
|
|
+ "apiToken": this.setApiToken('autoReg', 'register', this.currentTime[0], 'index')
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.$http.post('/index/register/autoReg', data, obj).then(res => {
|
|
|
+ if (res.data.code == 0) {
|
|
|
+ this.$dialog.alert({
|
|
|
+ mes: res.data.msg
|
|
|
+ });
|
|
|
+ } else if (res.data.code == 1) {
|
|
|
+ this.user_info = res.data.data;
|
|
|
+ // console.log(this.user_info)
|
|
|
+ localStorage.setItem('uid', res.data.data.id)
|
|
|
+ // 游客 token
|
|
|
+ localStorage.setItem("token", res.data.data.token);
|
|
|
+ localStorage.setItem("tutype", res.data.tutype);
|
|
|
+ //Websocket链接
|
|
|
+
|
|
|
+ this.$dialog.loading.close();
|
|
|
+ this.initWebSocket(this.apiToken);
|
|
|
+ //console.log(res.data.data)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ /******************************************/
|
|
|
+ //获取热门问题
|
|
|
+ getProblem() {
|
|
|
+ let obj = {
|
|
|
+ headers: {
|
|
|
+ // 'Content-Type': 'application/x-www-form-urlencoded',
|
|
|
+ "apiToken": this.setApiToken('index', 'robot', this.currentTime[0], 'index')
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.$http.post('/index/robot/index', {groups_id: 1, robotgroups_id: 1}, obj).then(res => {
|
|
|
+ //console.log(res.data.data);
|
|
|
+ this.problem = res.data.data;
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ /*******************************************/
|
|
|
+ //推送机器人消息
|
|
|
+ pushMessage(e) {
|
|
|
+ this.robot.push({
|
|
|
+ type: 'service',
|
|
|
+ content: {text: e}
|
|
|
+ });
|
|
|
+ this.automaticRolling();
|
|
|
+ },
|
|
|
+ checkSetType(){
|
|
|
+ let u = navigator.userAgent, app = navigator.appVersion;
|
|
|
+ let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //g
|
|
|
+ let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
|
|
|
+ if (isAndroid) {
|
|
|
+ return 'android';
|
|
|
+ }
|
|
|
+ if (isIOS) {
|
|
|
+ return 'ios';
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /*******************************************/
|
|
|
+ //转人工
|
|
|
+ turnArtificial(id) {
|
|
|
+ this.group = id;
|
|
|
+ // this.$dialog.loading.open('转接中...')
|
|
|
+ this.nloding('人工客服转接中');
|
|
|
+
|
|
|
+
|
|
|
+ if (this.isTurnArtifcial) {
|
|
|
+
|
|
|
+ let data = {
|
|
|
+ 'type': 'userInit',
|
|
|
+ data: {
|
|
|
+ 'uid': this.user_info.id,
|
|
|
+ 'name': this.user_info.name,
|
|
|
+ 'avatar': this.user_info.avatar,
|
|
|
+ 'group': this.group,
|
|
|
+ 'settype':this.checkSetType()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.socket_send(JSON.stringify(data));
|
|
|
+ this.isTurnArtifcial = false
|
|
|
+ // if(){
|
|
|
+ // }else{
|
|
|
+ // setTimeout(()=>{
|
|
|
+ // this.socket_send(JSON.stringify(data));
|
|
|
+ // this.isTurnArtifcial = false
|
|
|
+ // })
|
|
|
+ // }
|
|
|
+
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /******************************************/
|
|
|
+ // 消息发送
|
|
|
+ send() {
|
|
|
+ if (this.text_info == '') return;
|
|
|
+ let str = this.text_info;
|
|
|
+ let formatStr = str.replace(/\n|\r\n/g, "<br>");
|
|
|
+ let type = 'toRobot';
|
|
|
+ let data = {};
|
|
|
+ let obj = {
|
|
|
+ text: formatStr,
|
|
|
+ img: '',
|
|
|
+ type: ''
|
|
|
+ }
|
|
|
+ this.meme = false;
|
|
|
+ // console.log(JSON.stringify(obj))
|
|
|
+ //和人工发送消息
|
|
|
+ if (this.link_success) {
|
|
|
+ // if(this.getHistory){
|
|
|
+ // this.getHistory = false;
|
|
|
+ // }
|
|
|
+ data = {
|
|
|
+ from_name: this.user_info.name,
|
|
|
+ content: JSON.stringify(obj),
|
|
|
+ from_id: this.user_info.id,
|
|
|
+ avatar: '',
|
|
|
+ to_id: this.service_info.id,
|
|
|
+ to_name: this.service_info.name,
|
|
|
+ conversationId: this.conversationId,
|
|
|
+ }
|
|
|
+ type = 'chatMessage';
|
|
|
+ this.chatIndex = this.chat.length;
|
|
|
+ this.chat.push({
|
|
|
+ type: 'user',
|
|
|
+ time: '',
|
|
|
+ content: {text: this.turnFace(obj.text)}
|
|
|
+ })
|
|
|
+ } else {//和机器人聊天
|
|
|
+ data = {
|
|
|
+ groups_id: '1',
|
|
|
+ robot_name: formatStr,
|
|
|
+ robotgroups_id: '1',
|
|
|
+ }
|
|
|
+ // console.log(this.turnFace(formatStr));
|
|
|
+ type = 'toRobot';
|
|
|
+ //本地存放数据
|
|
|
+ this.robot.push({
|
|
|
+ type: 'user',
|
|
|
+ content: this.turnFace(formatStr) //obj
|
|
|
+ })
|
|
|
+ }
|
|
|
+ this.socket_send(JSON.stringify({type, data}))
|
|
|
+ this.text_info = '';
|
|
|
+ this.automaticRolling();
|
|
|
+ // console.log(data)
|
|
|
+ this.sendAudio();
|
|
|
+ // 还原输入框高度
|
|
|
+ let area = document.getElementById('textarea')
|
|
|
+ area.style.height = 36 + 'px';
|
|
|
+ },
|
|
|
+
|
|
|
+ // 消息发送音频
|
|
|
+ sendAudio() {
|
|
|
+ let send = new Audio();
|
|
|
+ send.src = '../../static/audio/send.wav';
|
|
|
+ send.play()
|
|
|
+ },
|
|
|
+ // 消息接收音频
|
|
|
+ receiveAudio() {
|
|
|
+ let receive = new Audio()
|
|
|
+ receive.src = "../../static/audio/receive.wav";
|
|
|
+ receive.play();
|
|
|
+ },
|
|
|
+
|
|
|
+ /*******************************************/
|
|
|
+ //获取转接人工客服列表
|
|
|
+ connectionService() {
|
|
|
+ // if (!this.isConnection) return
|
|
|
+ this.nloding('正在读取客服列表');
|
|
|
+ let obj = {
|
|
|
+ headers: {
|
|
|
+ "apiToken": this.setApiToken('index', 'groups', this.currentTime[0], 'index')
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // this.isConnection = false;
|
|
|
+ //api
|
|
|
+ this.$http.get('/index/groups/index', obj).then(res => {
|
|
|
+ this.closeNloading();
|
|
|
+ if (res.data.code == 1) {
|
|
|
+ this.robot.push({
|
|
|
+ type: 'artificial_service',
|
|
|
+ content: res.data.data
|
|
|
+ });
|
|
|
+ this.automaticRolling();
|
|
|
+ }
|
|
|
+ })
|
|
|
+ //this.hintSwitch.connection = true; //系统提示开关激活
|
|
|
+ // 此处为请求
|
|
|
+ },
|
|
|
+
|
|
|
+ /*******************************************/
|
|
|
+ //发送消息后自动滚动高度
|
|
|
+ automaticRolling() {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ let msg = document.getElementById('main') // 获取对象
|
|
|
+ // let input_box = document.getElementById('input_box') // 获取对象
|
|
|
+
|
|
|
+ //判断是否是苹果手机自代浏览器
|
|
|
+ if (/iPhone/.test(navigator.userAgent)) {
|
|
|
+ this.Safari_height = true; //input_box+'px';
|
|
|
+ }
|
|
|
+ if (/Linux/.test(navigator.userAgent)) {
|
|
|
+ this.Chrome_height = true; //input_box+'px';
|
|
|
+ }
|
|
|
+
|
|
|
+ msg.scrollTop = msg.scrollHeight // 滚动高度
|
|
|
+
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ /*******************************************/
|
|
|
+ //图片发送
|
|
|
+ uploadIMG(e) {
|
|
|
+ // console.log(e);
|
|
|
+
|
|
|
+ let self = this;
|
|
|
+ let files = e.target.files || e.dataTransfer.files;
|
|
|
+ if (!files.length) return;
|
|
|
+ let picavalue = files[0];
|
|
|
+ const isJPG = file.type == 'image/jpeg' || 'image/jpg' || 'image/png' || 'image/svg';
|
|
|
+ const isLt2M = picavalue.size / 1000 / 1000 > 2;
|
|
|
+
|
|
|
+ if (isLt2M) {
|
|
|
+ this.$dialog.notify({
|
|
|
+ mes: '图片过大不支持上传哦!',
|
|
|
+ timeout: 2000,
|
|
|
+ });
|
|
|
+ } else if (!isJPG) {
|
|
|
+ this.$dialog.notify({
|
|
|
+ mes: '只能上传图片哦!',
|
|
|
+ timeout: 2000,
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.$public.imgPreview(picavalue, function (imgSrc, formData) {
|
|
|
+ // let img = imgSrc;
|
|
|
+ // 数据结构请求
|
|
|
+ self.$http.uploadPost('/index/upload/uploadImg', formData).then(res => {
|
|
|
+ e.target.value = "";
|
|
|
+ // console.log(res.data.code)
|
|
|
+ if (res.data.code == 1) {
|
|
|
+ let type = 'toRobot';
|
|
|
+ let data = {};
|
|
|
+ let obj = {
|
|
|
+ text: '',
|
|
|
+ img: res.data.data.src,
|
|
|
+ type: ''
|
|
|
+ }
|
|
|
+ if (self.link_success) {
|
|
|
+ //和人工聊天发送图片
|
|
|
+ data = {
|
|
|
+ from_name: self.user_info.name,
|
|
|
+ content: JSON.stringify(obj),
|
|
|
+ from_id: self.user_info.id,
|
|
|
+ avatar: '',
|
|
|
+ to_id: self.service_info.id,
|
|
|
+ to_name: self.service_info.name,
|
|
|
+ conversationId: self.conversationId,
|
|
|
+ }
|
|
|
+ type = 'chatMessage';
|
|
|
+
|
|
|
+ self.chatIndex = self.chat.length;
|
|
|
+ //本地储存
|
|
|
+ self.chat.push({
|
|
|
+ type: 'user',
|
|
|
+ time:"",
|
|
|
+ content: {img: res.data.data.src}
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ } else {
|
|
|
+ //和机器发送图片
|
|
|
+ data = {
|
|
|
+ groups_id: '1',
|
|
|
+ robot_name: res.data.data.src,
|
|
|
+ robotgroups_id: '1',
|
|
|
+ }
|
|
|
+ type = 'toRobot';
|
|
|
+ //本地储存
|
|
|
+ self.robot.push({
|
|
|
+ type: 'user',
|
|
|
+ content: {img: res.data.data.src}
|
|
|
+ });
|
|
|
+ }
|
|
|
+ self.socket_send(JSON.stringify({type, data}))
|
|
|
+ self.automaticRolling();
|
|
|
+ }
|
|
|
+ })
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /**监听滚动事件,使消息能完全看见 */
|
|
|
+ scrollMain() {
|
|
|
+ let main = document.getElementById('main')
|
|
|
+ let footer = document.getElementById('input_box')
|
|
|
+ main.style.bottom = 0;
|
|
|
+ main.style.paddingBottom = (footer.offsetHeight - 30) + 'px'
|
|
|
+ },
|
|
|
+ /** 监听输入框滚动高度,并给textarea高度赋值*/
|
|
|
+ keyup_maxlength(){
|
|
|
+ let area = document.getElementById('textarea')
|
|
|
+ this.areaHeight = area.scrollHeight > 36 ? area.scrollHeight : 36;
|
|
|
+ let main = document.getElementById('main')
|
|
|
+ this.makeExpandingArea(area)
|
|
|
+ //console.log('screen:', window.screen.height, 'inner:', window.innerHeight)
|
|
|
+ // main.style.bottom = this.needScrollTop + 'px'
|
|
|
+ // console.log('foucus', this.needScrollTop)
|
|
|
+ // this.automaticRolling();
|
|
|
+ },
|
|
|
+ focus_maxlength() {
|
|
|
+ this.automaticRolling();
|
|
|
+ },
|
|
|
+ /** 兼容处理 */
|
|
|
+ makeExpandingArea(el) {
|
|
|
+ var timer = null;
|
|
|
+ //由于ie8有溢出堆栈问题,故调整了这里
|
|
|
+ var setStyle = function(el, auto) {
|
|
|
+ if (auto) el.style.height = 'auto';
|
|
|
+ el.style.height = el.scrollHeight + 'px';
|
|
|
+ }
|
|
|
+ var delayedResize = function(el) {
|
|
|
+ if (timer) {
|
|
|
+ clearTimeout(timer);
|
|
|
+ timer = null;
|
|
|
+ }
|
|
|
+ timer = setTimeout(function() {
|
|
|
+ setStyle(el)
|
|
|
+ }, 200);
|
|
|
+ }
|
|
|
+ if (el.addEventListener) {
|
|
|
+ el.addEventListener('input', function() {
|
|
|
+ setStyle(el, 1);
|
|
|
+ }, false);
|
|
|
+ setStyle(el)
|
|
|
+ } else if (el.attachEvent) {
|
|
|
+ el.attachEvent('onpropertychange', function() {
|
|
|
+ setStyle(el)
|
|
|
+ })
|
|
|
+ setStyle(el)
|
|
|
+ }
|
|
|
+ if (window.VBArray && window.addEventListener) { //IE9
|
|
|
+ el.attachEvent("onkeydown", function() {
|
|
|
+ var key = window.event.keyCode;
|
|
|
+ if (key == 8 || key == 46) delayedResize(el);
|
|
|
+
|
|
|
+ });
|
|
|
+ el.attachEvent("oncut", function() {
|
|
|
+ delayedResize(el);
|
|
|
+ }); //处理粘贴
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ /*******************************************/
|
|
|
+ //手机弹窗处理
|
|
|
+ inputShow(e) {
|
|
|
+ //console.log('a')
|
|
|
+ let ua = navigator.userAgent.toLowerCase();
|
|
|
+ if (ua.match(/iPhone\sOS/i) == "iphone os") {
|
|
|
+ var nowClientHeight = document.documentElement.clientHeight || document.body.clientHeight;
|
|
|
+
|
|
|
+ setTimeout(() => {
|
|
|
+ document.body.scrollTop = document.body.scrollHeight - (nowClientHeight / 2)
|
|
|
+ }, 200);
|
|
|
+ } else {
|
|
|
+ setTimeout(function () {
|
|
|
+ e.target.scrollIntoView({behavior: "smooth", block: "end"});
|
|
|
+ }, 100);
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /******************文字信息转表情******************/
|
|
|
+ turnFace(data) {
|
|
|
+ let str = data.match(/\#\[.*?\]\//g);
|
|
|
+ let arr = Array.from(new Set(str));
|
|
|
+ arr.forEach(e => {
|
|
|
+ let imgsrc = '';
|
|
|
+ for (let i = 0; i < this.frceArr.length; i++) {
|
|
|
+ let expText = e.slice(1, e.length - 1);
|
|
|
+ if (expText == this.frceArr[i]) {
|
|
|
+ imgsrc = '<img class="hover" src="' + require(`@/assets/${i}.gif`) + '"/>'
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ data = data.replace(new RegExp(`\\#\\[${e.substring(2, e.length - 2)}\\]\\/`, 'g'), imgsrc);
|
|
|
+ })
|
|
|
+ return data;
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ /*******************************************/
|
|
|
+ // 表情包开关
|
|
|
+ faceClick() {
|
|
|
+ this.meme = !this.meme;
|
|
|
+ },
|
|
|
+
|
|
|
+ /*******************************************/
|
|
|
+ //当表情被点击
|
|
|
+ memeImg(i) {
|
|
|
+ this.text_info = this.text_info + "#" + this.frceArr[i] + "/";
|
|
|
+ //this.text_info = this.text_info + '<img :src="' + require(`@/assets/${i}.gif`) +'"/>';
|
|
|
+ // console.log( this.text_info);
|
|
|
+ },
|
|
|
+
|
|
|
+ // /*******************************************/
|
|
|
+ // //验证码
|
|
|
+ // initialLoginCode() {
|
|
|
+ // this.loginCode = "";
|
|
|
+ // for (let i = 1; i <= 4; i++) {
|
|
|
+ // this.loginCode =
|
|
|
+ // this.loginCode + frce.arr[Math.floor(Math.random() * 32)];
|
|
|
+ // }
|
|
|
+ // },
|
|
|
+
|
|
|
+ /********************************************/
|
|
|
+ //显示隐藏评价
|
|
|
+ is_show_evaluate() {
|
|
|
+ if(localStorage.getItem('comtSuccess')){
|
|
|
+ this.$dialog.notify({
|
|
|
+ mes: '亲,您已经评价了...',
|
|
|
+ timeout: 3000,
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.evaluateState == 100) {
|
|
|
+ this.bottomShow = true;
|
|
|
+ } else {
|
|
|
+ if (!this.haveEvaluation) {
|
|
|
+ this.bottomShow = false;
|
|
|
+ } else {
|
|
|
+ this.$dialog.notify({
|
|
|
+ mes: '亲,您已经评价了...',
|
|
|
+ timeout: 5000,
|
|
|
+ callback: () => {
|
|
|
+ //console.log('我走咯!');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /*******************************************/
|
|
|
+ //切换评价状态
|
|
|
+ evaluateClick(type) {
|
|
|
+ // console.log(type);
|
|
|
+ this.evaluateState = type;
|
|
|
+ },
|
|
|
+
|
|
|
+ /*******************************************/
|
|
|
+ //提交评价信息
|
|
|
+ evaluateEsc() {
|
|
|
+
|
|
|
+ if (this.evaluateState != 100) {
|
|
|
+ this.bottomShow = false;
|
|
|
+ this.haveEvaluation = true; // 标识已评价
|
|
|
+ this.socket_send(JSON.stringify({
|
|
|
+ type: 'evaluate', data: {
|
|
|
+ evaluate_id: this.evaluateState,
|
|
|
+ conversationId: this.conversationId,
|
|
|
+ // evaluate_content:''
|
|
|
+ }
|
|
|
+ }))
|
|
|
+ let that = this
|
|
|
+ this.$dialog.notify({
|
|
|
+ mes: '感谢你的评价!',
|
|
|
+ timeout: 2000,
|
|
|
+ callback: () => {
|
|
|
+ //console.log('我走咯!');
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ } else {
|
|
|
+ this.$dialog.notify({
|
|
|
+ mes: '亲,请选择评价类型...',
|
|
|
+ timeout: 2000,
|
|
|
+ callback: () => {
|
|
|
+ //console.log('我走咯!');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /************************************************/
|
|
|
+ //人工聊天初始化
|
|
|
+ setInit() {
|
|
|
+ this.haveEvaluation = false;
|
|
|
+ this.chat = [];
|
|
|
+ this.evaluateState = 100;
|
|
|
+ this.hisSviceChat = [];
|
|
|
+ this.meme = false
|
|
|
+ // this.frceArr = [];//表情包代码
|
|
|
+ this.isConnection = true;
|
|
|
+ this.isExit = false;
|
|
|
+ this.service_info = {
|
|
|
+ avatar: '/static/customer/images/robot.png',
|
|
|
+ job_name: '001',
|
|
|
+ name: '智能客服',
|
|
|
+ signature: " "
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /* ****************获取聊天次数****************** */
|
|
|
+ getChatNum() {
|
|
|
+ this.$http.get('/index/evaluate/minRound', {
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/x-www-form-urlencoded',
|
|
|
+ 'apiToken': this.setApiToken('minround', 'evaluate', this.currentTime[0], 'index')
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ if (res.data.code == 1) {
|
|
|
+ this.chatNum = res.data.data.systemconfig_data;
|
|
|
+ // console.log(this.chatNum, '聊天限制')
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 留言知识库返回到主页
|
|
|
+ returnIndex(data) {
|
|
|
+ console.log(data)
|
|
|
+ this.knowledge = data
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 视图挂载前
|
|
|
+ */
|
|
|
+ mounted() {
|
|
|
+ this.source.appuid = this.$public.getQueryString('appuid');//用户标识
|
|
|
+ this.source.appid = this.$public.getQueryString('appid');//用户来源
|
|
|
+ this.frceArr = frce.frce;
|
|
|
+ //console.log(this.source);
|
|
|
+ //页面初始化获取系统时间第一步
|
|
|
+ //console.log(this.$md5('userwordscustomer-servicewords1562169600service'));
|
|
|
+ this.$dialog.loading.open('网络连接中...');
|
|
|
+ this.$http.get('/index/index/systime?t=' + 100).then(res => {
|
|
|
+ if (res.data.code == 1) {
|
|
|
+ this.logo = res.data.data.logo;
|
|
|
+ this.currentTime = res.data.data.time.split(' ')
|
|
|
+ this.currentTime[0] = (new Date(this.currentTime[0].replace(/-/g, '/')).getTime()) / 1000;
|
|
|
+
|
|
|
+ // console.log( this.currentTime[0] );
|
|
|
+ this.apiToken = this.$md5('customer-service' + window.location.origin);
|
|
|
+ //匿名注册
|
|
|
+ this.registered();
|
|
|
+ //获取机器人热门问题
|
|
|
+ this.getProblem();
|
|
|
+ //获取配置信息
|
|
|
+ this.getChatNum();
|
|
|
+ }
|
|
|
+
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ destroyed() {
|
|
|
+ this.setInit();
|
|
|
+ this.websock.close() //离开路由之后断开websocket连接
|
|
|
+ this.lockReconnect = true;
|
|
|
+ clearTimeout(this.reconnectData); //离开清除 timeout
|
|
|
+ clearTimeout(this.timeoutObj); //离开清除 timeout
|
|
|
+ clearTimeout(this.serverTimeoutObj); //离开清除 timeout
|
|
|
+ },
|
|
|
+ // 计算
|
|
|
+ computed: {
|
|
|
+ inputmsg() {
|
|
|
+ return this.text_info;
|
|
|
+ },
|
|
|
+ iboxheight(){
|
|
|
+ return this.ibox_height;
|
|
|
+ },
|
|
|
+ // 需要额外滚动的高度,大小为键盘高度加上输入框的高度
|
|
|
+ needScrollTop: function () {
|
|
|
+ if(this.innerHeight > 0) {
|
|
|
+ // return (this.innerHeight > window.innerHeight ? this.innerHeight : innerHeight )
|
|
|
+ // - window.innerHeight + this.areaHeight -36
|
|
|
+ return window.screen.height - window.innerHeight + this.areaHeight -36
|
|
|
+ } else {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ // 监听
|
|
|
+ watch: {},
|
|
|
+ // 组件生命周期结束销毁阶段
|
|
|
+ beforeDestroy() {
|
|
|
+ this.timers = false;
|
|
|
+ }
|
|
|
+ };
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+ #textarea {
|
|
|
+ flex: 1;
|
|
|
+ height: 36px;
|
|
|
+ margin: 15px;
|
|
|
+ border: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .logo {
|
|
|
+ margin: 0 0.1rem;
|
|
|
+ width: 0.4rem;
|
|
|
+ height: 0.4rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 聊天 */
|
|
|
+ .memeImg {
|
|
|
+ width: 0.6rem;
|
|
|
+ height: 0.6rem;
|
|
|
+ margin: 0.15rem 0.4rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .dialogueA {
|
|
|
+ padding-left: 0.3rem;
|
|
|
+ padding-right: 0.3rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .dialogueB {
|
|
|
+ padding-right: 0.3rem;
|
|
|
+ padding-left: 0.3rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .left {
|
|
|
+ position: relative;
|
|
|
+ z-index: 99;
|
|
|
+ background: #fff;
|
|
|
+ }
|
|
|
+
|
|
|
+ .left::after {
|
|
|
+ position: absolute;
|
|
|
+ content: "";
|
|
|
+ display: inline-block;
|
|
|
+ left: -0.08rem;
|
|
|
+ top: 0.2rem;
|
|
|
+ width: 0.125rem;
|
|
|
+ height: 0.2rem;
|
|
|
+ background: #fff;
|
|
|
+ transform: skewX(30deg);
|
|
|
+ z-index: -1;
|
|
|
+ border-left: 0.02rem solid #dfdfdf;
|
|
|
+ border-top: 0.02rem solid #dfdfdf;
|
|
|
+ }
|
|
|
+
|
|
|
+ .right {
|
|
|
+ position: relative;
|
|
|
+ z-index: 99;
|
|
|
+ background: #5ea0f7;
|
|
|
+ border: 0.02rem solid #5ea0f7;
|
|
|
+ }
|
|
|
+
|
|
|
+ .right::after {
|
|
|
+ position: absolute;
|
|
|
+ content: "";
|
|
|
+ display: inline-block;
|
|
|
+ right: -0.07rem;
|
|
|
+ top: 0.2rem;
|
|
|
+ width: 0.125rem;
|
|
|
+
|
|
|
+ height: 0.2rem;
|
|
|
+ background: #5ea0f7;
|
|
|
+ transform: skewX(-30deg);
|
|
|
+ z-index: -1;
|
|
|
+ border-left: 0.02rem solid #5ea0f7;
|
|
|
+ border-top: 0.02rem solid #5ea0f7;
|
|
|
+ }
|
|
|
+
|
|
|
+ .service {
|
|
|
+ width: 100%;
|
|
|
+ color: #555;
|
|
|
+ font-size: 0.28rem;
|
|
|
+ padding-top: 1rem;
|
|
|
+ background: #f5f5f5;
|
|
|
+ }
|
|
|
+
|
|
|
+ .header {
|
|
|
+ position: fixed;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ width: 100%;
|
|
|
+ z-index: 999;
|
|
|
+ height: 1rem;
|
|
|
+ background: linear-gradient(
|
|
|
+ 90deg,
|
|
|
+ rgba(22, 84, 209, 1) 0%,
|
|
|
+ rgba(9, 52, 173, 1) 100%
|
|
|
+ );
|
|
|
+ box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
|
|
|
+ font-size: 0.34rem;
|
|
|
+ color: #fff;
|
|
|
+ padding: 0 0.3rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .main {
|
|
|
+ position: relative;
|
|
|
+ box-sizing: border-box;
|
|
|
+ height: 83vh;
|
|
|
+ overflow-x: hidden;
|
|
|
+ overflow-y: auto;
|
|
|
+ padding:0.4rem 0.3rem;
|
|
|
+ padding-top:0;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn {
|
|
|
+ display: inline-block;
|
|
|
+ padding: 0 0.36rem;
|
|
|
+ text-align: center;
|
|
|
+ line-height: 0.4rem;
|
|
|
+ background: rgba(221, 221, 221, 1);
|
|
|
+ border-radius: 0.3rem;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 0.24rem;
|
|
|
+ max-width: 6rem;
|
|
|
+ margin: 0 auto;
|
|
|
+ margin-top: 0.3rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn .click {
|
|
|
+ color: #5ea0f7;
|
|
|
+ }
|
|
|
+
|
|
|
+ .btnRouter {
|
|
|
+ color: #5ea0f7;
|
|
|
+ }
|
|
|
+
|
|
|
+ .systemDialogue {
|
|
|
+ min-height: 0.8rem;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .manUserDialogue {
|
|
|
+ min-height: 1rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .manPlatformDialogue {
|
|
|
+ min-height: 1rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .user {
|
|
|
+ padding: 0.2rem;
|
|
|
+ display: inline-block;
|
|
|
+ border-radius: 0.1rem;
|
|
|
+ font-size: 0.28rem;
|
|
|
+ color: #fff;
|
|
|
+ max-width: 19.1rem;
|
|
|
+ table-layout:fixed;
|
|
|
+ word-break: break-all;
|
|
|
+ text-align: left;
|
|
|
+ }
|
|
|
+
|
|
|
+ .HeadPortrait {
|
|
|
+ width: 1rem;
|
|
|
+ height: 1rem;
|
|
|
+ /* background: #ddd; */
|
|
|
+ border-radius: 0.1rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .HeadPortrait img {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .icon {
|
|
|
+ width: 0.32rem;
|
|
|
+ height: 0.32rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .icon-msg {
|
|
|
+ margin-top: 0.06rem;
|
|
|
+ margin-left: 0.2rem;
|
|
|
+ width: 0.32rem;
|
|
|
+ height: 0.32rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .customerService {
|
|
|
+ background: #ffffff;
|
|
|
+ padding: 0.2rem;
|
|
|
+ display: inline-block;
|
|
|
+ border-radius: 0.1rem;
|
|
|
+ font-size: 0.28rem;
|
|
|
+ border: 1px solid rgba(223, 223, 223, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ .customerService {
|
|
|
+ /* min-height: 1rem; */
|
|
|
+ }
|
|
|
+
|
|
|
+ .system {
|
|
|
+ width: 100%;
|
|
|
+ border: 0.01rem solid rgba(223, 223, 223, 1);
|
|
|
+ border-radius: 0.1rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ div /deep/ .yd-accordion-head {
|
|
|
+ /* border-radius: 0.1rem; */
|
|
|
+ border-bottom: 0.01rem solid rgb(238, 238, 238);
|
|
|
+ padding: 0 0.2rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ div /deep/ .yd-accordion-title, div /deep/ .yd-accordion-head-arrow {
|
|
|
+ min-height: 0.8rem !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ div /deep/ .yd-textarea textarea {
|
|
|
+ -webkit-user-select: auto;
|
|
|
+ }
|
|
|
+
|
|
|
+ .footer {
|
|
|
+ display: flex;
|
|
|
+ min-height: 1.2rem;
|
|
|
+ box-shadow: 0px -5px 5px rgba(0, 0, 0, 0.05);
|
|
|
+ background: #fff;
|
|
|
+ width: 100%;
|
|
|
+ position: fixed;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ z-index: 1000;
|
|
|
+ }
|
|
|
+
|
|
|
+ .input {
|
|
|
+ width: 60%;
|
|
|
+ min-height: 1.2rem;
|
|
|
+ padding-top: 0.4rem;
|
|
|
+ padding-bottom: 0.4rem;
|
|
|
+ border: none;
|
|
|
+ padding-right: 0.3rem;
|
|
|
+ padding-left: 0.3rem;
|
|
|
+ font-size: 0.28rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .send {
|
|
|
+ flex: 0 0 130px;
|
|
|
+ margin-right: 10px;
|
|
|
+ text-align: right;
|
|
|
+ /* position: absolute;
|
|
|
+ right: 0;
|
|
|
+ top: 0; */
|
|
|
+ background: #fff;
|
|
|
+ height: 1.2rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .memeBox {
|
|
|
+ height: 3rem;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .send img {
|
|
|
+ vertical-align: middle;
|
|
|
+ margin-right: 0.4rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .artificial {
|
|
|
+ margin: 0.3rem 0 0 1.3rem;
|
|
|
+ width: 77%;
|
|
|
+ border: 0.01rem solid #dfdfdf;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 0.1rem;
|
|
|
+ padding: 0 0.2rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ div /deep/ .yd-accordion-head-arrow:after {
|
|
|
+ border: none;
|
|
|
+ width: 0.3rem;
|
|
|
+ height: 0.3rem;
|
|
|
+ background: url("../assets/addright.png") no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ transform: rotate(0deg);
|
|
|
+ }
|
|
|
+
|
|
|
+ div /deep/ .yd-accordion-head-arrow.yd-accordion-rotated:after {
|
|
|
+ transform: rotate(-270deg);
|
|
|
+ }
|
|
|
+
|
|
|
+ div /deep/ .yd-accordion {
|
|
|
+ border-radius: 0.1rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ div /deep/ .yd-accordion-content {
|
|
|
+ border-radius: 0.1rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .imgSrc img {
|
|
|
+ width: 1.2rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .leftHader {
|
|
|
+ height: 1rem;
|
|
|
+ background: linear-gradient(
|
|
|
+ 90deg,
|
|
|
+ rgba(22, 84, 209, 1) 0%,
|
|
|
+ rgba(9, 52, 173, 1) 100%
|
|
|
+ );
|
|
|
+ box-shadow: 0 0.03rem 0.03rem rgba(0, 0, 0, 0.2);
|
|
|
+ padding: 0 0.3rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .leftMain-top {
|
|
|
+ margin-top: 0.4rem;
|
|
|
+ font-size: 0.28rem;
|
|
|
+ line-height: 0.45rem;
|
|
|
+ padding: 0 0.3rem;
|
|
|
+ color: #666;
|
|
|
+ }
|
|
|
+
|
|
|
+ .leftMain-top span {
|
|
|
+ color: #999;
|
|
|
+ }
|
|
|
+
|
|
|
+ .leftMain-top > div {
|
|
|
+ width: 50%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .leftMain-center {
|
|
|
+ margin-top: 0.3rem;
|
|
|
+ color: #666;
|
|
|
+ line-height: 0.5rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .leftMain-chenter span {
|
|
|
+ color: #999;
|
|
|
+ font-size: 0.28rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .evaluate {
|
|
|
+ height: 1.7rem;
|
|
|
+ background: #fff;
|
|
|
+ border: 0.01rem solid #ddd;
|
|
|
+ border-radius: 0.1rem;
|
|
|
+ color: #666;
|
|
|
+ margin-top: 0.3rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .evaluateBtn {
|
|
|
+ width: 1.4rem;
|
|
|
+ height: 0.6rem;
|
|
|
+ border: none;
|
|
|
+ background: #f04992;
|
|
|
+ color: #fff;
|
|
|
+ border-radius: 0.1rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ div /deep/ .yd-popup {
|
|
|
+ border-radius: 0.2rem 0.2rem 0 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ div /deep/ .yd-popup-content {
|
|
|
+ }
|
|
|
+
|
|
|
+ .evaluatebtn > div p {
|
|
|
+ height: 50%;
|
|
|
+ width: 100%;
|
|
|
+ text-align: center;
|
|
|
+ margin-top: 0.14rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .evaluatebtn > div {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .evaluateBox {
|
|
|
+ margin: 0 0.2rem;
|
|
|
+ height: 1.5rem;
|
|
|
+ border: 0.01rem solid #ddd;
|
|
|
+ border-radius: 0.1rem;
|
|
|
+ background: #f5f5f5;
|
|
|
+ }
|
|
|
+
|
|
|
+ .evaluateBox textarea {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ background: #f5f5f5;
|
|
|
+ border: none;
|
|
|
+ border-radius: 0.1rem;
|
|
|
+ padding: 0.2rem;
|
|
|
+ color: #999;
|
|
|
+ font-size: 0.28rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .sub {
|
|
|
+ margin: 0 0.2rem;
|
|
|
+ background: linear-gradient(
|
|
|
+ 90deg,
|
|
|
+ rgba(22, 84, 209, 1) 0%,
|
|
|
+ rgba(9, 52, 173, 1) 100%
|
|
|
+ );
|
|
|
+ box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
|
|
|
+ height: 1rem;
|
|
|
+ font-size: 0.34rem;
|
|
|
+ color: #fff;
|
|
|
+ border-radius: 0.1rem;
|
|
|
+ margin-top: 0.4rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ div /deep/ .yd-popup-content {
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 0.1rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .loginInput {
|
|
|
+ height: 0.8rem;
|
|
|
+ border: 0.01rem solid #ddd;
|
|
|
+ background: #f5f5f5;
|
|
|
+ border-radius: 0.1rem;
|
|
|
+ margin-top: 0.5rem;
|
|
|
+ padding: 0.2rem;
|
|
|
+ font-size: 0.28rem;
|
|
|
+ margin: 0.2rem;
|
|
|
+ margin-top: 0.5rem;
|
|
|
+ width: 94%;
|
|
|
+ color: #999;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 留言 */
|
|
|
+ .leave-header {
|
|
|
+ height: 1rem;
|
|
|
+ background: linear-gradient(
|
|
|
+ 90deg,
|
|
|
+ rgba(22, 84, 209, 1) 0%,
|
|
|
+ rgba(9, 52, 173, 1) 100%
|
|
|
+ );
|
|
|
+ box-shadow: 0px 3px 3px rgba(0, 0, 0, 0.2);
|
|
|
+ color: #fff;
|
|
|
+ font-size: 0.34rem;
|
|
|
+ padding: 0 0.3rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .leave-main {
|
|
|
+ height: 10rem;
|
|
|
+ background: #f5f5f5;
|
|
|
+ font-size: 0.28rem;
|
|
|
+ padding: 0.3rem 0.3rem 0.2rem 0.3rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .leave-main > div {
|
|
|
+ height: 1.3rem;
|
|
|
+ margin-bottom: 0.2rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .leave-main > div input {
|
|
|
+ height: 0.8rem;
|
|
|
+ border: 0.01rem solid #ddd;
|
|
|
+ border-radius: 0.1rem;
|
|
|
+ background: #fff;
|
|
|
+ padding: 0.2rem;
|
|
|
+ width: 100%;
|
|
|
+ margin-top: 0.1rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .leave-main-txt {
|
|
|
+ background: #fff;
|
|
|
+ padding: 0.2rem;
|
|
|
+ border: 0.01rem solid #ddd;
|
|
|
+ border-radius: 0.1rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .imgMsg {
|
|
|
+ height: 1.5rem;
|
|
|
+ padding: 0 0.2rem;
|
|
|
+ margin-top: 0.1rem;
|
|
|
+ font-size: 0.24rem;
|
|
|
+ background: #fff;
|
|
|
+ border: 0.01rem solid #ddd;
|
|
|
+ border-radius: 0.1rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .yd-cell-box {
|
|
|
+ width: 60%;
|
|
|
+ min-height: 1.2rem;
|
|
|
+
|
|
|
+ border: none;
|
|
|
+ padding-right: 0.3rem;
|
|
|
+ padding-left: 0.3rem;
|
|
|
+ border-bottom: 0.01rem solid rgb(221, 221, 221);
|
|
|
+ }
|
|
|
+
|
|
|
+ div /deep/ .yd-textarea > textarea {
|
|
|
+ min-height: 1.2rem;
|
|
|
+ font-size: 0.28rem;
|
|
|
+ padding-top: 0.2rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .yd-textarea {
|
|
|
+ padding: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .yd-cell-box {
|
|
|
+ margin: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .yd-cell-item {
|
|
|
+ padding: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ div /deep/ .yd-cell:after {
|
|
|
+ height: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ div /deep/ .yd-textarea-counter {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ .promptBox {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ height: 26px;
|
|
|
+ margin: 10px 0 10px;
|
|
|
+ /* line-height: 26px; */
|
|
|
+ }
|
|
|
+
|
|
|
+ .promptBoxH {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ height: 50px;
|
|
|
+ margin: 10px 0 10px;
|
|
|
+ /* line-height: 26px; */
|
|
|
+ }
|
|
|
+
|
|
|
+ .prompt {
|
|
|
+ line-height: 25px;
|
|
|
+ text-align: center;
|
|
|
+ background: #DDDDDD;
|
|
|
+ border-radius: 30px;
|
|
|
+ width: 140px;
|
|
|
+ color: #FFFFFF;
|
|
|
+ font-size: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .help {
|
|
|
+ width: 80%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .help .prompt {
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .row .rightAlignment {
|
|
|
+ text-align: right;
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+ #main{
|
|
|
+ /* margin-bottom: .3rem; */
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ *留言知识库
|
|
|
+ */
|
|
|
+
|
|
|
+</style>
|