|
|
@@ -1,1318 +1,1318 @@
|
|
|
<template>
|
|
|
- <div class="row allAlignment">
|
|
|
- <leftNav />
|
|
|
- <div>
|
|
|
- <hader/>
|
|
|
- <div class="row">
|
|
|
- <messageCenter></messageCenter>
|
|
|
- <!-- 聊天列表模块 -->
|
|
|
- <div class="sessionList">
|
|
|
- <el-collapse>
|
|
|
- <el-collapse-item>
|
|
|
- <template slot="title">
|
|
|
- <span>会话中 <span>({{sessionList.length }})</span></span>
|
|
|
- <!-- <span class="sessionList_span">排队人数(10)</span> -->
|
|
|
- </template>
|
|
|
- <div :class="{session_choose:dataIndex ==index && sessionType ==1}" class="user session_style" @click="chooseDialogue(1,index)" v-for="(item,index) in sessionList">
|
|
|
- <div class="row allAlignment item-center">
|
|
|
- <span style="font-weight:bold;color:#666;font-size:14px;">{{item.name}}</span>
|
|
|
- <span style="color:#999;font-size:.12px;">{{item.intime}}</span>
|
|
|
- </div>
|
|
|
- <div class="row allAlignment item-center">
|
|
|
- <div style="width:90%;font-size:.12px;" class="ellipsis">
|
|
|
- <span v-html="item.text" ></span>
|
|
|
- </div>
|
|
|
- <span v-if="item.num > 0" class="markNumber">{{item.num}}</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </el-collapse-item>
|
|
|
- <el-collapse-item>
|
|
|
- <template slot="title">
|
|
|
- <span>已离线<span>({{offlineList.length }})</span></span>
|
|
|
- </template>
|
|
|
- <div :class="{session_choose:dataIndex ==index && sessionType ==2}" class="user session_style" @click="chooseDialogue(2,index)" v-for="(item,index) in offlineList">
|
|
|
- <div class="row allAlignment item-center">
|
|
|
- <span style="font-weight:bold;color:#999;font-size:14px;">{{item.name}}</span>
|
|
|
- <span style="color:#999;font-size:12px;">{{item.intime}}</span>
|
|
|
- </div>
|
|
|
- <div class="row allAlignment item-center">
|
|
|
- <div style="width:90%;color:#999;font-size:12px;" class="ellipsis">
|
|
|
- <span v-html="item.text"></span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </el-collapse-item>
|
|
|
- <el-collapse-item>
|
|
|
- <template slot="title">
|
|
|
- <span>排队中<span>({{lineUp.length}})</span></span>
|
|
|
- </template>
|
|
|
- <div class="user" v-for="item in lineUp">
|
|
|
- <div class="row allAlignment item-center">
|
|
|
- <span style="font-weight:bold;color:#666;font-size:14px;">{{item}}</span>
|
|
|
- <span style="color:#999;font-size:12px;">{{item}}</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </el-collapse-item>
|
|
|
- </el-collapse>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 聊天模块 -->
|
|
|
- <div class="chat" >
|
|
|
- <div class="chatTop row item-center allAlignment" style="padding:0 10px;">
|
|
|
- <p class="ellipsis"
|
|
|
- style="width:40%;font-size:14px;font-weight:bold;color:#666;"
|
|
|
- >{{sessionName}}</p>
|
|
|
- <div class="row item-center rightAlignment" style="width:50%;height:100%;color:#999;font-size:12px;">
|
|
|
- <p class="row item-center" @click="getServiceList()">
|
|
|
- <!-- 转接 -->
|
|
|
- <el-popover placement="right" width="400" trigger="click">
|
|
|
- <el-table :data="transferList">
|
|
|
- <el-table-column width="150" property="groupname" label="组名"></el-table-column>
|
|
|
- <el-table-column width="100" property="kfname" label="姓名"></el-table-column>
|
|
|
- <el-table-column label="操作">
|
|
|
- <template slot-scope="scope">
|
|
|
- <el-button size="mini" @click="transfer(scope.$index, scope.row)">转入</el-button>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- </el-table>
|
|
|
- <el-button slot="reference"> <i style="font-size:14px" class="el-icon-refresh"></i> 转接</el-button>
|
|
|
- </el-popover>
|
|
|
- </p>
|
|
|
- <p class="row item-center" style="margin-left:10px;">
|
|
|
- <el-button size="mini" type="text" @click="open"><i style="font-size:15px" class="el-icon-close"></i> 结束服务</el-button>
|
|
|
- </p>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="chat-box scroll" id='chat_box' >
|
|
|
- <div v-for="(item,index) in data" :key="index">
|
|
|
- <!-- 系统转接 -->
|
|
|
- <!-- <div class="row center" v-if="item.type == 'system'">
|
|
|
- <p style="font-size:12px;color:#bbb;">09.30.45 由问答机器人转接</p>
|
|
|
- </div> -->
|
|
|
-
|
|
|
- <!-- 用户消息 -->
|
|
|
- <div style="padding:0 10px;margin-top:20px;" v-if="item.type == 'user'">
|
|
|
- <div
|
|
|
- style="height:37px;font-size:.12px;color:#bbb;"
|
|
|
- class="row item-center"
|
|
|
- >{{item.time}}</div>
|
|
|
- <div class="row">
|
|
|
- <div v-if="item.content.img != ''" >
|
|
|
- <!-- :fit="contain " style="width: 100%; height: 100px"-->
|
|
|
- <el-image style="width: 200px; height: 100px" :src="img_http + item.content.img" :fit="fit" ></el-image>
|
|
|
- </div>
|
|
|
- <p v-else class="chatMsg user_box" v-html="item.content.text" ></p>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 客服消息 -->
|
|
|
- <div style="padding:0 10px;margin-top:20px;" class="rightAlignment" v-if="item.type == 'service'" >
|
|
|
- <div style="height:37px;font-size:12px;color:#bbb;" class="row item-center rightAlignment">{{item.time}}</div>
|
|
|
- <div class="row item-center rightAlignment">
|
|
|
- <div v-if="item.content.img !=''" >
|
|
|
- <!-- :fit="contain" style="background:#F5F5F5; border-radius: 10px 0 10px 10px;"-->
|
|
|
- <el-image style="width: 200px; height: 100px" :src="img_http + item.content.img" :fit="fit" ></el-image>
|
|
|
- </div>
|
|
|
- <p v-else class="chatMsg message_box" v-html="item.content.text" ></p>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- <div class="key column allAlignment">
|
|
|
- <div class="frce row item-center allAlignment">
|
|
|
- <div class="row ">
|
|
|
- <img class="hover" :src="isFrce?require('@/assets/img/frcea.png'):require('@/assets/img/frce.png')"
|
|
|
- @click="frceClick" style="margin-right:16px;"/>
|
|
|
- <input type="file" id="file" style="display:none;" @change="uploadIMG" />
|
|
|
- <label for="file" class="row item-center" style="height:100%">
|
|
|
- <img class="hover" src="@/assets/img/img.png" />
|
|
|
- </label>
|
|
|
- </div>
|
|
|
- <div >
|
|
|
- <i :class="{disable : is_eva_btn }" @click="evaluation()" class="el-icon-postcard hover evaluation"></i>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <textarea draggable="false" class="input scroll" id="input" v-model="inputValue"
|
|
|
- @keyup.enter="listenEnter($event)" @keyup.ctrl.enter="lineFeed()"></textarea>
|
|
|
- <div class="row rightAlignment" style="width: 100%;">
|
|
|
- <div @click="sendMessage()" class="msgInputBtn row center">发送</div>
|
|
|
- </div>
|
|
|
- <div class="frceBox scroll" v-if="isFrce">
|
|
|
- <div class="row wrap average">
|
|
|
- <p class="row center" v-for="(item,index) in frceArr" :key="item.id">
|
|
|
- <img class="hover" @click="frceCenterClick(item)" :src="require(`@/assets/img/${index}.gif`)" />
|
|
|
- </p>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 快捷回复模块 -->
|
|
|
- <div class="FastReply">
|
|
|
- <div class="FastReplyHader row item-center">快捷回复</div>
|
|
|
- <div class="FastReplySwitch row item-center average">
|
|
|
- <p :class="FastReplySwitch=='one'?'active':''" class="hover" @click="FastReplySwitchClick('one')">公有库</p>
|
|
|
- <span style="width:1px;height:18px;background:#ccc;display: block;"></span>
|
|
|
- <p :class="FastReplySwitch=='tow'?'active':''"
|
|
|
- class="hover"
|
|
|
- @click="FastReplySwitchClick('tow')"
|
|
|
- >私有库</p>
|
|
|
- </div>
|
|
|
- <!-- <div class="serch row center">
|
|
|
- <div class="serchBox">
|
|
|
- <input placeholder="搜索快捷回复" v-model="serch" type="text" />
|
|
|
- <img src="@/assets/img/serch.png" />
|
|
|
- </div>
|
|
|
- </div> -->
|
|
|
- <!-- <div> -->
|
|
|
- <!-- <el-collapse>
|
|
|
- <el-collapse-item>
|
|
|
- <template slot="title" name="el-icon-caret-bottom">
|
|
|
- <span>常用语</span>
|
|
|
- </template> -->
|
|
|
- <div style="padding: 0.4rem 0;">
|
|
|
- <!-- <ul class="FastReplyList"> -->
|
|
|
- <!-- <li @click="getLanguage(item.content)" class="row cursor_text" v-for="item in FastReply.sysWords" :key="item.id"> -->
|
|
|
- <div @click="getLanguage(item.content)" class="row cursor_text item-center" v-for="item in FastReply.sysWords" :key="item.id" v-if="FastReplySwitch == 'one'">
|
|
|
- <span class="title_span" style=" width: 30%">#{{item.title}}</span>
|
|
|
- <div class="ellipsis" style=" width: 70%">
|
|
|
-
|
|
|
- <span class="content_span">{{item.content}}</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
-
|
|
|
- <!-- </li> -->
|
|
|
-
|
|
|
- <div @click="getLanguage(item.content)" class="row cursor_text item-center" v-for="item in FastReply.userWords" :key="item.id" v-if="FastReplySwitch == 'tow'">
|
|
|
- <span class="title_span" style=" width: 30%">#{{item.title}}</span>
|
|
|
- <div class="ellipsis" style=" width: 70%">
|
|
|
-
|
|
|
- <span class="content_span">{{item.content}}</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- <li class="row cursor_text" v-for="item in FastReply.userWords" :key="item.id">
|
|
|
- <div v-if="FastReplySwitch == 'tow'" class="row item-center">
|
|
|
- <p style="margin-right:10px;color:#666;font-size:14px;font-weight: bold;"
|
|
|
- >#{{item.title}}</p>
|
|
|
- <p class="ellipsis" style="width: 60%; color:#999;font-size:14px;">{{item.content}}</p>
|
|
|
- </div>
|
|
|
- </li> -->
|
|
|
- <!-- </ul> -->
|
|
|
- </div>
|
|
|
- <!-- </el-collapse-item>
|
|
|
- </el-collapse> -->
|
|
|
- <!-- </div> -->
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 用户信息模块 -->
|
|
|
- <div class="userinfo">
|
|
|
- <div style="color:#666;font-weight:bold;font-size:14px;">用户信息</div>
|
|
|
- <div style="margin-top:10px;color:#999;font-size:14px;" class="userData wrap">
|
|
|
- <div class="user_info_box">
|
|
|
- <span>姓名:</span>
|
|
|
- <input class="user_text" v-model="session_user_info.name" type="text">
|
|
|
- </div>
|
|
|
- <div class="user_info_box">
|
|
|
- <span>手机:</span>
|
|
|
- <input class="user_text" v-model="session_user_info.phone" type="text">
|
|
|
- </div>
|
|
|
- <div class="user_info_box">
|
|
|
- <span>邮箱:</span>
|
|
|
- <input class="user_text" v-model="session_user_info.email" type="text">
|
|
|
- </div>
|
|
|
- <div class="user_info_box">
|
|
|
- <span>地址:</span>
|
|
|
- <input class="user_text" v-model="session_user_info.addres" type="text">
|
|
|
- </div>
|
|
|
- <p>访客备注:</p>
|
|
|
- </div>
|
|
|
- <textarea draggable="false" class="userDataInput" v-model="session_user_info.remark" style="margin-top:10px;" ></textarea>
|
|
|
- <div class="userBtn row center">保存</div>
|
|
|
-
|
|
|
- <div style="color:#666;font-weight:bold;font-size:14px;margin-top:30px;">访问信息</div>
|
|
|
- <div style="margin-top:10px;color:#999;font-size:14px;" class="userData wrap">
|
|
|
- <p>来源渠道:{{session_user_info.website}}</p>
|
|
|
- <p>IP地址:{{session_user_info.ip}}</p>
|
|
|
- <p>来源终端:{{session_user_info.browse}}</p>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ <div class="row allAlignment">
|
|
|
+ <leftNav />
|
|
|
+ <div>
|
|
|
+ <hader/>
|
|
|
+ <messageCenter></messageCenter>
|
|
|
+ <div class="row">
|
|
|
+ <!-- 聊天列表模块 -->
|
|
|
+ <div class="sessionList">
|
|
|
+ <el-collapse>
|
|
|
+ <el-collapse-item>
|
|
|
+ <template slot="title">
|
|
|
+ <span>会话中 <span>({{sessionList.length }})</span></span>
|
|
|
+ <!-- <span class="sessionList_span">排队人数(10)</span> -->
|
|
|
+ </template>
|
|
|
+ <div :class="{session_choose:dataIndex ==index && sessionType ==1}" class="user session_style" @click="chooseDialogue(1,index)" v-for="(item,index) in sessionList">
|
|
|
+ <div class="row allAlignment item-center">
|
|
|
+ <span style="font-weight:bold;color:#666;font-size:14px;">{{item.name}}</span>
|
|
|
+ <span style="color:#999;font-size:.12px;">{{item.intime}}</span>
|
|
|
+ </div>
|
|
|
+ <div class="row allAlignment item-center">
|
|
|
+ <div style="width:90%;font-size:.12px;" class="ellipsis">
|
|
|
+ <span v-html="item.text" ></span>
|
|
|
+ </div>
|
|
|
+ <span v-if="item.num > 0" class="markNumber">{{item.num}}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-collapse-item>
|
|
|
+ <el-collapse-item>
|
|
|
+ <template slot="title">
|
|
|
+ <span>已离线<span>({{offlineList.length }})</span></span>
|
|
|
+ </template>
|
|
|
+ <div :class="{session_choose:dataIndex ==index && sessionType ==2}" class="user session_style" @click="chooseDialogue(2,index)" v-for="(item,index) in offlineList">
|
|
|
+ <div class="row allAlignment item-center">
|
|
|
+ <span style="font-weight:bold;color:#999;font-size:14px;">{{item.name}}</span>
|
|
|
+ <span style="color:#999;font-size:12px;">{{item.intime}}</span>
|
|
|
+ </div>
|
|
|
+ <div class="row allAlignment item-center">
|
|
|
+ <div style="width:90%;color:#999;font-size:12px;" class="ellipsis">
|
|
|
+ <span v-html="item.text"></span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-collapse-item>
|
|
|
+ <el-collapse-item>
|
|
|
+ <template slot="title">
|
|
|
+ <span>排队中<span>({{lineUp.length}})</span></span>
|
|
|
+ </template>
|
|
|
+ <div class="user" v-for="item in lineUp">
|
|
|
+ <div class="row allAlignment item-center">
|
|
|
+ <span style="font-weight:bold;color:#666;font-size:14px;">{{item}}</span>
|
|
|
+ <span style="color:#999;font-size:12px;">{{item}}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-collapse-item>
|
|
|
+ </el-collapse>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 聊天模块 -->
|
|
|
+ <div class="chat" >
|
|
|
+ <div class="chatTop row item-center allAlignment" style="padding:0 10px;">
|
|
|
+ <p class="ellipsis"
|
|
|
+ style="width:40%;font-size:14px;font-weight:bold;color:#666;"
|
|
|
+ >{{sessionName}}</p>
|
|
|
+ <div class="row item-center rightAlignment" style="width:50%;height:100%;color:#999;font-size:12px;">
|
|
|
+ <p class="row item-center" @click="getServiceList()">
|
|
|
+ <!-- 转接 -->
|
|
|
+ <el-popover placement="right" width="400" trigger="click">
|
|
|
+ <el-table :data="transferList">
|
|
|
+ <el-table-column width="150" property="groupname" label="组名"></el-table-column>
|
|
|
+ <el-table-column width="100" property="kfname" label="姓名"></el-table-column>
|
|
|
+ <el-table-column label="操作">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-button size="mini" @click="transfer(scope.$index, scope.row)">转入</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <el-button slot="reference"> <i style="font-size:14px" class="el-icon-refresh"></i> 转接</el-button>
|
|
|
+ </el-popover>
|
|
|
+ </p>
|
|
|
+ <p class="row item-center" style="margin-left:10px;">
|
|
|
+ <el-button size="mini" type="text" @click="open"><i style="font-size:15px" class="el-icon-close"></i> 结束服务</el-button>
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="chat-box scroll" id='chat_box' >
|
|
|
+ <div v-for="(item,index) in data" :key="index">
|
|
|
+ <!-- 系统转接 -->
|
|
|
+ <!-- <div class="row center" v-if="item.type == 'system'">
|
|
|
+ <p style="font-size:12px;color:#bbb;">09.30.45 由问答机器人转接</p>
|
|
|
+ </div> -->
|
|
|
+
|
|
|
+ <!-- 用户消息 -->
|
|
|
+ <div style="padding:0 10px;margin-top:20px;" v-if="item.type == 'user'">
|
|
|
+ <div
|
|
|
+ style="height:37px;font-size:.12px;color:#bbb;"
|
|
|
+ class="row item-center"
|
|
|
+ >{{item.time}}</div>
|
|
|
+ <div class="row">
|
|
|
+ <div v-if="item.content.img != ''" >
|
|
|
+ <!-- :fit="contain " style="width: 100%; height: 100px"-->
|
|
|
+ <el-image style="width: 200px; height: 100px" :src="img_http + item.content.img" :fit="fit" ></el-image>
|
|
|
+ </div>
|
|
|
+ <p v-else class="chatMsg user_box" v-html="item.content.text" ></p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 客服消息 -->
|
|
|
+ <div style="padding:0 10px;margin-top:20px;" class="rightAlignment" v-if="item.type == 'service'" >
|
|
|
+ <div style="height:37px;font-size:12px;color:#bbb;" class="row item-center rightAlignment">{{item.time}}</div>
|
|
|
+ <div class="row item-center rightAlignment">
|
|
|
+ <div v-if="item.content.img !=''" >
|
|
|
+ <!-- :fit="contain" style="background:#F5F5F5; border-radius: 10px 0 10px 10px;"-->
|
|
|
+ <el-image style="width: 200px; height: 100px" :src="img_http + item.content.img" :fit="fit" ></el-image>
|
|
|
+ </div>
|
|
|
+ <p v-else class="chatMsg message_box" v-html="item.content.text" ></p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ <div class="key column allAlignment">
|
|
|
+ <div class="frce row item-center allAlignment">
|
|
|
+ <div class="row ">
|
|
|
+ <img class="hover" :src="isFrce?require('@/assets/img/frcea.png'):require('@/assets/img/frce.png')"
|
|
|
+ @click="frceClick" style="margin-right:16px;"/>
|
|
|
+ <input type="file" id="file" style="display:none;" @change="uploadIMG" />
|
|
|
+ <label for="file" class="row item-center" style="height:100%">
|
|
|
+ <img class="hover" src="@/assets/img/img.png" />
|
|
|
+ </label>
|
|
|
+ </div>
|
|
|
+ <div >
|
|
|
+ <i :class="{disable : is_eva_btn }" @click="evaluation()" class="el-icon-postcard hover evaluation"></i>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <textarea draggable="false" class="input scroll" id="input" v-model="inputValue"
|
|
|
+ @keyup.enter="listenEnter($event)" @keyup.ctrl.enter="lineFeed()"></textarea>
|
|
|
+ <div class="row rightAlignment" style="width: 100%;">
|
|
|
+ <div @click="sendMessage()" class="msgInputBtn row center">发送</div>
|
|
|
+ </div>
|
|
|
+ <div class="frceBox scroll" v-if="isFrce">
|
|
|
+ <div class="row wrap average">
|
|
|
+ <p class="row center" v-for="(item,index) in frceArr" :key="item.id">
|
|
|
+ <img class="hover" @click="frceCenterClick(item)" :src="require(`@/assets/img/${index}.gif`)" />
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 快捷回复模块 -->
|
|
|
+ <div class="FastReply">
|
|
|
+ <div class="FastReplyHader row item-center">快捷回复</div>
|
|
|
+ <div class="FastReplySwitch row item-center average">
|
|
|
+ <p :class="FastReplySwitch=='one'?'active':''" class="hover" @click="FastReplySwitchClick('one')">公有库</p>
|
|
|
+ <span style="width:1px;height:18px;background:#ccc;display: block;"></span>
|
|
|
+ <p :class="FastReplySwitch=='tow'?'active':''"
|
|
|
+ class="hover"
|
|
|
+ @click="FastReplySwitchClick('tow')"
|
|
|
+ >私有库</p>
|
|
|
+ </div>
|
|
|
+ <!-- <div class="serch row center">
|
|
|
+ <div class="serchBox">
|
|
|
+ <input placeholder="搜索快捷回复" v-model="serch" type="text" />
|
|
|
+ <img src="@/assets/img/serch.png" />
|
|
|
+ </div>
|
|
|
+ </div> -->
|
|
|
+ <!-- <div> -->
|
|
|
+ <!-- <el-collapse>
|
|
|
+ <el-collapse-item>
|
|
|
+ <template slot="title" name="el-icon-caret-bottom">
|
|
|
+ <span>常用语</span>
|
|
|
+ </template> -->
|
|
|
+ <div style="padding: 0.4rem 0;">
|
|
|
+ <!-- <ul class="FastReplyList"> -->
|
|
|
+ <!-- <li @click="getLanguage(item.content)" class="row cursor_text" v-for="item in FastReply.sysWords" :key="item.id"> -->
|
|
|
+ <div @click="getLanguage(item.content)" class="row cursor_text item-center" v-for="item in FastReply.sysWords" :key="item.id" v-if="FastReplySwitch == 'one'">
|
|
|
+ <span class="title_span" style=" width: 30%">#{{item.title}}</span>
|
|
|
+ <div class="ellipsis" style=" width: 70%">
|
|
|
+
|
|
|
+ <span class="content_span">{{item.content}}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+
|
|
|
+ <!-- </li> -->
|
|
|
+
|
|
|
+ <div @click="getLanguage(item.content)" class="row cursor_text item-center" v-for="item in FastReply.userWords" :key="item.id" v-if="FastReplySwitch == 'tow'">
|
|
|
+ <span class="title_span" style=" width: 30%">#{{item.title}}</span>
|
|
|
+ <div class="ellipsis" style=" width: 70%">
|
|
|
+
|
|
|
+ <span class="content_span">{{item.content}}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- <li class="row cursor_text" v-for="item in FastReply.userWords" :key="item.id">
|
|
|
+ <div v-if="FastReplySwitch == 'tow'" class="row item-center">
|
|
|
+ <p style="margin-right:10px;color:#666;font-size:14px;font-weight: bold;"
|
|
|
+ >#{{item.title}}</p>
|
|
|
+ <p class="ellipsis" style="width: 60%; color:#999;font-size:14px;">{{item.content}}</p>
|
|
|
+ </div>
|
|
|
+ </li> -->
|
|
|
+ <!-- </ul> -->
|
|
|
+ </div>
|
|
|
+ <!-- </el-collapse-item>
|
|
|
+ </el-collapse> -->
|
|
|
+ <!-- </div> -->
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 用户信息模块 -->
|
|
|
+ <div class="userinfo">
|
|
|
+ <div style="color:#666;font-weight:bold;font-size:14px;">用户信息</div>
|
|
|
+ <div style="margin-top:10px;color:#999;font-size:14px;" class="userData wrap">
|
|
|
+ <div class="user_info_box">
|
|
|
+ <span>姓名:</span>
|
|
|
+ <input class="user_text" v-model="session_user_info.name" type="text">
|
|
|
+ </div>
|
|
|
+ <div class="user_info_box">
|
|
|
+ <span>手机:</span>
|
|
|
+ <input class="user_text" v-model="session_user_info.phone" type="text">
|
|
|
+ </div>
|
|
|
+ <div class="user_info_box">
|
|
|
+ <span>邮箱:</span>
|
|
|
+ <input class="user_text" v-model="session_user_info.email" type="text">
|
|
|
+ </div>
|
|
|
+ <div class="user_info_box">
|
|
|
+ <span>地址:</span>
|
|
|
+ <input class="user_text" v-model="session_user_info.addres" type="text">
|
|
|
+ </div>
|
|
|
+ <p>访客备注:</p>
|
|
|
+ </div>
|
|
|
+ <textarea draggable="false" class="userDataInput" v-model="session_user_info.remark" style="margin-top:10px;" ></textarea>
|
|
|
+ <div class="userBtn row center">保存</div>
|
|
|
+
|
|
|
+ <div style="color:#666;font-weight:bold;font-size:14px;margin-top:30px;">访问信息</div>
|
|
|
+ <div style="margin-top:10px;color:#999;font-size:14px;" class="userData wrap">
|
|
|
+ <p>来源渠道:{{session_user_info.website}}</p>
|
|
|
+ <p>IP地址:{{session_user_info.ip}}</p>
|
|
|
+ <p>来源终端:{{session_user_info.browse}}</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import "@/css/index.css";
|
|
|
-import leftNav from "@/components/leftNav";
|
|
|
-import hader from "@/components/hader";
|
|
|
-import messageCenter from "@/components/messageCenter";
|
|
|
-
|
|
|
-export default {
|
|
|
- name: "TheCurrentSession",
|
|
|
- data() {
|
|
|
- return {
|
|
|
- /***********************************/
|
|
|
- inputValue: "", //输入框内容
|
|
|
- isFrce: false, //表情包开关
|
|
|
- frceArr: [], //表情包数组
|
|
|
- data: [], //当前对话数据
|
|
|
- dataIndex:0,//定位当前会话,默认是0
|
|
|
- FastReply: "", //快捷回复
|
|
|
- FastReplySwitch: "one", //快捷回复开关
|
|
|
- user_info:'',//用户信息
|
|
|
- token: "",
|
|
|
- time: "",
|
|
|
- sessionList:[],//会话列表
|
|
|
- offlineList:[],//离线列表
|
|
|
- transferList:[],//转接列表
|
|
|
- sessionType:1,//选择列表状态默认未1(1是会话中,2是离线)
|
|
|
- lineUp:[],//排队列表
|
|
|
- conversationId:'',//会话工单
|
|
|
- sessionName:'',//当前会话用户名字
|
|
|
- session_user_info:{},//当前会话用户信息
|
|
|
- img_http:'http://kfadmin.bocai186.com',//图片路径域
|
|
|
- //img_http:'http://192.168.2.186:8090',//图片路径域
|
|
|
- fit:'scale-down',//图片渲染样式
|
|
|
- is_eva_btn:true,//
|
|
|
- trigger_condition:0,//评价触发条件
|
|
|
- webTime:'',//客服会话时间
|
|
|
- session_marked:'',//客服当前会话标记
|
|
|
- sensitive:[],//敏感词数据
|
|
|
- };
|
|
|
- },
|
|
|
- /**
|
|
|
- *
|
|
|
- */
|
|
|
- methods: {
|
|
|
- /************回车提交************/
|
|
|
- listenEnter(event){
|
|
|
- if (event.keyCode === 13) {
|
|
|
- this.inputValue = this.inputValue.replace(/\s/g,'')
|
|
|
- // this.inputValue = this.inputValue.replace(/\n /g,'')
|
|
|
- this.sendMessage(); // 发送文本
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /************ctrl+center 换行***********/
|
|
|
- lineFeed(){
|
|
|
- this.inputValue = this.inputValue + '\n'
|
|
|
- },
|
|
|
- /******************消息数据接收********************/
|
|
|
- chatMessage(redata){
|
|
|
- // console.log('列表',this.sessionList)
|
|
|
- if(redata.type == "pong" ) return
|
|
|
- console.log('消息',redata)
|
|
|
- // 用户接入数据
|
|
|
- if(redata.message_type == "connect"){
|
|
|
- this.conversationId = redata.data.conversationId;
|
|
|
- redata.data.user_info.conversationId = redata.data.conversationId;
|
|
|
- let isTrue = true;
|
|
|
- //匹配是否是离线用户上线
|
|
|
- if(this.offlineList.length > 0){
|
|
|
- for(let i = 0; i < this.offlineList.length ; i++){
|
|
|
- //匹配离线列表是否有这个用户
|
|
|
- if(this.offlineList[i].id == redata.data.user_info.id ){
|
|
|
- //匹配离线列表是否存会话工单未结束
|
|
|
- if(this.offlineList[i].conversationId == redata.data.conversationId){
|
|
|
- //工单号未结束的数据处理
|
|
|
- if(this.sessionType == 2 && i == this.dataIndex){
|
|
|
- this.data = [];
|
|
|
- this.data = this.offlineList[i].data;
|
|
|
- }
|
|
|
- redata.data.user_info.data = this.offlineList[i].data
|
|
|
- }else{
|
|
|
- //工单号已结束数据处理
|
|
|
- if(this.dataIndex == 0 && this.sessionList.length == 0){
|
|
|
- this.sessionName = redata.data.user_info.name;
|
|
|
- this.data = [];
|
|
|
- }
|
|
|
- redata.data.user_info.data = [];
|
|
|
- }
|
|
|
- //将离线状态用户删除
|
|
|
- this.offlineList.splice(i,1);
|
|
|
- this.$store.dispatch("SET_OFFLINE",this.offlineList);
|
|
|
- this.get_user_info(this.offlineList);
|
|
|
- isTrue = false;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }else{
|
|
|
- this.sessionType = 1;
|
|
|
- this.sessionName = '';
|
|
|
- this.data = [];
|
|
|
- }
|
|
|
- if(isTrue){
|
|
|
- if(this.dataIndex == 0 && this.sessionList.length == 0){
|
|
|
- this.sessionName = redata.data.user_info.name;
|
|
|
- this.data = [];
|
|
|
- }
|
|
|
- redata.data.user_info.data = [];
|
|
|
- }
|
|
|
- redata.data.user_info.intime = this.time[1];
|
|
|
- redata.data.user_info.num = 0;
|
|
|
- this.sessionList.push(redata.data.user_info);
|
|
|
- this.get_user_info(this.sessionList);
|
|
|
- //将数据储存到vuex里面
|
|
|
- this.$store.dispatch("SET_SESSION",this.sessionList);
|
|
|
- // this.$store.getters.getLimit
|
|
|
- }
|
|
|
-
|
|
|
- //用户离线后会话窗口切换
|
|
|
- if(redata.message_type == "userClose"){
|
|
|
- for(let i = 0 ; i < this.sessionList.length; i++){
|
|
|
- //匹配会话中离线用户
|
|
|
- if(this.sessionList[i].id == redata.data.id ){
|
|
|
- //把数据添加到离线列表
|
|
|
- this.offlineList.push(this.sessionList[i]);
|
|
|
- this.$store.dispatch("SET_OFFLINE",this.offlineList);
|
|
|
- //用户选中状态会话中处理
|
|
|
- if(this.sessionType == 1){
|
|
|
- //判断会话中列表长度
|
|
|
- if(this.sessionList.length > 1){
|
|
|
- //删除会话列表离线用户
|
|
|
- this.sessionList.splice(i,1);
|
|
|
- this.$store.dispatch("SET_SESSION",this.sessionList);
|
|
|
- //获取会话中列表第一个会话消息
|
|
|
- this.dataIndex = 0;
|
|
|
- this.sessionName = this.sessionList[0].name;
|
|
|
- this.data = [];
|
|
|
- this.data = this.sessionList[0].data;
|
|
|
- }else{
|
|
|
- this.sessionType = 2;
|
|
|
- this.dataIndex = 0;
|
|
|
- // if(this.offlineList.length >0){
|
|
|
- // }else{}
|
|
|
- this.sessionName =this.offlineList[0].name;
|
|
|
- this.data = this.offlineList[0].data;
|
|
|
- //删除会话列表离线用户
|
|
|
- this.sessionList.splice(i,1);
|
|
|
- this.$store.dispatch("SET_SESSION",this.sessionList);
|
|
|
- }
|
|
|
- }else{
|
|
|
- //删除会话列表离线用户
|
|
|
- this.sessionList.splice(i,1);
|
|
|
- this.$store.dispatch("SET_SESSION",this.sessionList);
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- this.get_user_info(this.sessionList);
|
|
|
- }
|
|
|
-
|
|
|
- //用户断开链接会话窗口切换
|
|
|
- if(redata.message_type == "delUser"){
|
|
|
- let isTrue = true;
|
|
|
- //会话中列表匹配
|
|
|
- for(let i = 0 ; i < this.sessionList.length; i++){
|
|
|
- //判断会话中列表是否结束会话
|
|
|
- if(this.sessionList[i].id == redata.data.id){
|
|
|
- //删除会话列表断线关闭的用户信息
|
|
|
- this.sessionList.splice(i,1);
|
|
|
- this.$store.dispatch("SET_SESSION",this.sessionList);
|
|
|
- if(this.sessionType == 1){
|
|
|
- //处理会话显现状态
|
|
|
- if(this.dataIndex == i){
|
|
|
- if(this.sessionList.length >1){
|
|
|
- this.sessionName = this.sessionList[0].name;
|
|
|
- this.data = this.sessionList[0].data;
|
|
|
- this.get_user_info(this.sessionList);
|
|
|
- }else{
|
|
|
- this.sessionName = '';
|
|
|
- this.data = [];
|
|
|
- this.get_user_info(this.offlineList);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- isTrue = false;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- //离线列表匹配
|
|
|
- if(isTrue){
|
|
|
- for(let i = 0 ; i < this.offlineList.length; i++){
|
|
|
- //判断离线列表是否结束会话
|
|
|
- if(this.offlineList[i].id == redata.data.id){
|
|
|
- console.log('离线列');
|
|
|
- //删除离线列表中断线关闭的用户信息
|
|
|
- this.offlineList.splice(i,1);
|
|
|
- this.$store.dispatch("SET_OFFLINE",this.offlineList);
|
|
|
- if(this.sessionType == 2){
|
|
|
- if(this.dataIndex == i){
|
|
|
- console.log('别乱动 大于1','来了吗');
|
|
|
- if(this.offlineList.length > 1){
|
|
|
- this.data = this.offlineList[0].data;
|
|
|
- this.sessionName = this.offlineList[0].name;
|
|
|
- this.get_user_info(this.offlineList);
|
|
|
- }else{
|
|
|
- console.log('别乱动 小于1','来了吗');
|
|
|
- this.data = [];
|
|
|
- this.sessionName = '';
|
|
|
- this.get_user_info(this.sessionList);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //接收用户消息数据
|
|
|
- if(redata.message_type == "chatMessage"){
|
|
|
- let dataIndex = 0;
|
|
|
- //匹配是那个用户回的消息
|
|
|
- for(let i = 0 ; i < this.sessionList.length ; i++){
|
|
|
- if(this.sessionList[i].id == redata.data.id ){
|
|
|
- dataIndex = i;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- //获取当前回复消息对象
|
|
|
- let chatList = this.sessionList[dataIndex]
|
|
|
- redata.data.type = 'user';
|
|
|
- redata.data.content = JSON.parse(redata.data.content);
|
|
|
- //这个地方转
|
|
|
-
|
|
|
- redata.data.content.text = this.turnFace(redata.data.content.text);
|
|
|
- //更新会话时间
|
|
|
- this.$set(chatList,'intime',redata.data.time);
|
|
|
-
|
|
|
- //更新会话列表中最新回复消息
|
|
|
- if(redata.data.content.text){
|
|
|
- this.$set(chatList,'text',redata.data.content.text)
|
|
|
- }
|
|
|
-
|
|
|
- //将消息添加对应的会话列表中
|
|
|
- chatList.data.push(redata.data);
|
|
|
- //判断是否是当前对话信息
|
|
|
- if(dataIndex == this.dataIndex){
|
|
|
- this.data =[];
|
|
|
- this.data = chatList.data;
|
|
|
- }else{
|
|
|
- let num = chatList.num;
|
|
|
- //console.log(chatList.num);
|
|
|
- this.$set(chatList,'num',num+1)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //接收系统操作信息状态在线客服列表
|
|
|
- if(redata.message_type == "onlinekfs"){
|
|
|
- this.transferList = [];
|
|
|
- this.transferList = this.transferList.concat(redata.data);
|
|
|
- }
|
|
|
-
|
|
|
- //
|
|
|
- if(redata.message_type == "webTime"){
|
|
|
- // this.webTime = redata.data.webTime
|
|
|
- this.$set(this.data[this.session_marked],'time',redata.data.webTime);
|
|
|
- }
|
|
|
-
|
|
|
- //客服手动转接用户成功
|
|
|
- if(redata.message_type == "trunconnect"){
|
|
|
- this.sessionList.splice(this.dataIndex,1);
|
|
|
- this.$message({
|
|
|
- message: '转接用户成功...',
|
|
|
- type: 'success'
|
|
|
- });
|
|
|
- if(this.sessionList.length >1 ){
|
|
|
- this.dataIndex =0;
|
|
|
- // this.data = []
|
|
|
-
|
|
|
- }else{
|
|
|
- this.data = [];
|
|
|
- this.sessionName ='';
|
|
|
- // if(this.offlineList.length >0){
|
|
|
- // this.data = [];
|
|
|
- // this.sessionName ='';
|
|
|
- // }else{
|
|
|
- // this.data = [];
|
|
|
- // this.sessionName ='';
|
|
|
- // }
|
|
|
- }
|
|
|
- }
|
|
|
- this.automaticRolling();
|
|
|
- },
|
|
|
- /******************文字信息转表情******************/
|
|
|
- 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.$frce.length ; i++){
|
|
|
- let expText = e.slice(1,e.length-1);
|
|
|
- if(expText == this.$frce[i]){
|
|
|
- imgsrc = '<img class="hover" src="'+require(`@/assets/img/${i}.gif`)+'"/>'
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- data = data.replace(new RegExp(`\\#\\[${e.substring(2,e.length-2)}\\]\\/`,'g'),imgsrc);
|
|
|
- })
|
|
|
- return data;
|
|
|
- },
|
|
|
-
|
|
|
- /*********************图片发送*********************/
|
|
|
- uploadIMG(e) {
|
|
|
- //console.log(e);
|
|
|
- let self = this;
|
|
|
- let files = e.target.files || e.dataTransfer.files;
|
|
|
- if (!files.length) return;
|
|
|
- let picavalue = files[0];
|
|
|
- //console.log(picavalue);
|
|
|
- if (picavalue.size / 1000 > 20000) {
|
|
|
- this.$message({
|
|
|
- message: "图片过大不支持上传",
|
|
|
- type: "warning"
|
|
|
- });
|
|
|
- } else {
|
|
|
- this.$public.imgPreview(picavalue, function(imgSrc,formData) {
|
|
|
- // 数据结构请求
|
|
|
- self.post('api/'+self.$ports.uploadImg,formData).then(res=>{
|
|
|
- //console.log(res.data.data.src)
|
|
|
- if(res.data.code == 1){
|
|
|
- let isFirst = true;
|
|
|
- //判断客服是否发送的第一句话
|
|
|
- if(self.data.length >0){
|
|
|
- for(let i = 0 ; i < self.data.length ; i++ ){
|
|
|
- if(self.data[i].type == 'service' ){
|
|
|
- isFirst =false;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- let obj = {
|
|
|
- text:'',
|
|
|
- img:res.data.data.src,
|
|
|
- type:false,
|
|
|
- };
|
|
|
- let chatList = self.sessionList[self.dataIndex];
|
|
|
- chatList.data.push({type:'service', content:obj ,time:self.time[1]});
|
|
|
- self.data = [];
|
|
|
- self.data = chatList.data;
|
|
|
- let type ='chatMessage';
|
|
|
- let data = {
|
|
|
- from_name:self.user_info.user_name,//发送者
|
|
|
- from_avatar:self.user_info.avatar,//发送者头像
|
|
|
- from_id:"KF"+self.user_info.id,//发送者id
|
|
|
- content:JSON.stringify(obj),
|
|
|
- to_id: self.sessionList[self.dataIndex].id,
|
|
|
- to_name:self.sessionList[self.dataIndex].name,
|
|
|
- conversationId:self.sessionList[self.dataIndex].conversationId,
|
|
|
- isFirst:isFirst,//是否是第一句话
|
|
|
- sensitiveNumber:0,//敏感词次数
|
|
|
- }
|
|
|
- self.websocketsend(JSON.stringify({type,data}))
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
- })
|
|
|
- });
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /*****************转接会话用户确认******************/
|
|
|
- transfer(e){
|
|
|
-
|
|
|
- if(this.sessionList.length > 0){
|
|
|
- this.$confirm('此操作将当前用户转出, 是否继续?', '温馨提示!', {
|
|
|
- confirmButtonText: '确定',
|
|
|
- cancelButtonText: '取消',
|
|
|
- type: 'warning'
|
|
|
- }).then(() => {
|
|
|
- let type ="changeOtherhKeFu";
|
|
|
- let data={
|
|
|
- conversationId:this.sessionType == 1 ? this.sessionList[this.dataIndex].conversationId : this.offlineList[this.dataIndex].conversationId,
|
|
|
- togroup:this.transferList[e].groupid,
|
|
|
- fromgroup:this.user_info.group_id,
|
|
|
- toukfuid:this.transferList[e].kfuid ,
|
|
|
- fromkfuid:"KF"+this.user_info.id,
|
|
|
- uid:this.sessionType == 1 ? this.sessionList[this.dataIndex].id : this.offlineList[this.dataIndex].id,
|
|
|
- word:'',
|
|
|
- }
|
|
|
- //console.log({type,data});
|
|
|
- this.websocketsend(JSON.stringify({type,data}))
|
|
|
- }).catch(() => {
|
|
|
-
|
|
|
- })
|
|
|
- }else{
|
|
|
- this.$message({
|
|
|
- message: '亲!您没有和用户会话怎么能转接呢。',
|
|
|
- type: 'warning'
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- /******************获取客服人员列表*****************/
|
|
|
- getServiceList(){
|
|
|
- //console.log(12313);
|
|
|
- this.websocketsend(JSON.stringify({"type":"getkfonlines"}))
|
|
|
- },
|
|
|
-
|
|
|
- /*****************切换用户会话对象******************/
|
|
|
- chooseDialogue(type,index){
|
|
|
- let data =[];
|
|
|
- this.sessionType = type;
|
|
|
- this.dataIndex = index;
|
|
|
- if(type == 1){
|
|
|
- data = this.sessionList[index].data;
|
|
|
- this.session_user_info = this.sessionList[index];
|
|
|
- this.$set(this.sessionList[index],'num',0);
|
|
|
- this.sessionName = this.sessionList[index].name
|
|
|
- }else if(type == 2){
|
|
|
- data = this.offlineList[index].data;
|
|
|
- this.sessionName = this.offlineList[index].name;
|
|
|
- this.session_user_info = this.offlineList[index];
|
|
|
- }
|
|
|
- this.data = data;
|
|
|
- },
|
|
|
-
|
|
|
- /***************关闭当前和用户聊天对话***************/
|
|
|
- open(){
|
|
|
- let _this =this;
|
|
|
- if(this.sessionType == 1){
|
|
|
- if(this.sessionList.length < 1 )return
|
|
|
- }else{
|
|
|
- if(this.offlineList.length < 1)return
|
|
|
- }
|
|
|
- this.$confirm('此操作将关闭和当前用户通话, 是否继续?', '温馨提示!', {
|
|
|
- confirmButtonText: '确定',
|
|
|
- cancelButtonText: '取消',
|
|
|
- type: 'warning'
|
|
|
- }).then(() => {
|
|
|
- let to_id = this.sessionType == 1 ? this.sessionList[this.dataIndex].id :this.offlineList[this.dataIndex].id;
|
|
|
- let conversationId = this.sessionType == 1 ? this.sessionList[this.dataIndex].conversationId :this.offlineList[this.dataIndex].conversationId;
|
|
|
- let data = {
|
|
|
- "type":"kfCloseUser",
|
|
|
- data:{
|
|
|
- to_id,
|
|
|
- kf_id:"KF"+_this.user_info.id,
|
|
|
- group_id:_this.user_info.group_id,
|
|
|
- conversationId:conversationId,
|
|
|
- }
|
|
|
- }
|
|
|
- if(this.sessionType == 1){
|
|
|
- this.sessionList.splice(this.dataIndex,1);
|
|
|
- if(this.sessionList.length> 0){
|
|
|
- this.data = this.sessionList[0];
|
|
|
- this.sessionName = this.sessionList[0].name;
|
|
|
- }else{
|
|
|
- this.data = [];
|
|
|
- this.sessionName = '';
|
|
|
- }
|
|
|
- }else{
|
|
|
- this.offlineList.splice(this.dataIndex,1);
|
|
|
- this.data = [];
|
|
|
- this.sessionName = '';
|
|
|
- }
|
|
|
-
|
|
|
- this.websocketsend(JSON.stringify(data))
|
|
|
- }).catch(() => {
|
|
|
- // this.$message({
|
|
|
- // type: 'info',
|
|
|
- // message: '已取消删除'
|
|
|
- // });
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- /*****************数据发送方法调用******************/
|
|
|
- websocketsend(Data) {
|
|
|
- this.$websocket.send(Data);
|
|
|
- this.automaticRolling();
|
|
|
- },
|
|
|
-
|
|
|
- /*********************发送消息*********************/
|
|
|
- sendMessage(){
|
|
|
- console.log();
|
|
|
- if(!this.inputValue) return
|
|
|
- if(this.sessionList.length == 0) {
|
|
|
- this.$message({
|
|
|
- message: '只能给在线用户发送消息哦...',
|
|
|
- type: 'warning'
|
|
|
- });
|
|
|
- return false;
|
|
|
- }
|
|
|
- // if(this.offlineList.length <= 0 ) return
|
|
|
- let isFirst = true,sensitiveNumber=0;
|
|
|
- this.isFrce = false;
|
|
|
- //判断客服是否发送的第一句话
|
|
|
- if(this.data.length >0){
|
|
|
- for(let i = 0 ; i < this.data.length ; i++ ){
|
|
|
- if(this.data[i].type == 'service' ){
|
|
|
- isFirst =false;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- //判断客服敏感词报警次数
|
|
|
- let obj = {
|
|
|
- text: this.inputValue,
|
|
|
- img:'',
|
|
|
- type:false,
|
|
|
- }
|
|
|
- let type ='chatMessage';
|
|
|
- let data = {
|
|
|
- from_name:this.user_info.user_name,//发送者
|
|
|
- from_avatar:this.user_info.avatar,//发送者头像
|
|
|
- from_id:"KF"+this.user_info.id,//发送者id
|
|
|
- content:JSON.stringify(obj),
|
|
|
- to_id: this.sessionList[this.dataIndex].id,
|
|
|
- to_name:this.sessionList[this.dataIndex].name,
|
|
|
- conversationId:this.sessionList[this.dataIndex].conversationId,
|
|
|
- isFirst:isFirst,//是否是第一句话
|
|
|
- sensitiveNumber:sensitiveNumber,//敏感词次数
|
|
|
- }
|
|
|
- let chatList = this.sessionList[this.dataIndex];
|
|
|
- //检测发送信息是否含有敏感词
|
|
|
- let sensitive_data= this.$public.shieldingKeyword(this.turnFace(this.inputValue),this.sensitive);
|
|
|
-
|
|
|
- //有敏感词提示并且禁止发送
|
|
|
- if(sensitive_data.num == 0 ){
|
|
|
- // 本地储存
|
|
|
- chatList.data.push({type:'service', content:{
|
|
|
- text:this.turnFace(this.inputValue),
|
|
|
- img:'',
|
|
|
- type:false,
|
|
|
- } ,time:this.time[1]});
|
|
|
-
|
|
|
- this.data = [];
|
|
|
- //标记当前会话位置
|
|
|
- this.session_marked = chatList.data.length -1;
|
|
|
- this.data = chatList.data;
|
|
|
- this.websocketsend(JSON.stringify({type,data}))
|
|
|
- this.inputValue = '';
|
|
|
- }else{
|
|
|
- this.$message({
|
|
|
- message: '敏感词'+sensitive_data.text,
|
|
|
- type: 'warning'
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- /******************开启或关闭表情包******************/
|
|
|
- frceClick() {
|
|
|
- this.isFrce = !this.isFrce;
|
|
|
- },
|
|
|
-
|
|
|
- /*******************发送评价指令*******************/
|
|
|
- evaluation(){
|
|
|
- console.log(this.sessionList[this.dataIndex]);
|
|
|
- if(!this.is_eva_btn && this.sessionType == 1){
|
|
|
- this.$message({
|
|
|
- message: '评价指令已发送',
|
|
|
- type: 'success'
|
|
|
- });
|
|
|
- let type = 'getEvaluate';
|
|
|
- let data = {
|
|
|
- conversationId:this.sessionList[this.dataIndex].conversationId,
|
|
|
- to_id:this.sessionList[this.dataIndex].id,
|
|
|
- }
|
|
|
- this.websocketsend(JSON.stringify({type,data}));
|
|
|
- this.is_eva_btn = true;
|
|
|
- }else if(this.sessionType == 2){
|
|
|
- this.$message.error('用户已离线指令无法发送');
|
|
|
- }else {
|
|
|
- this.$message.error('评价指令无法发送');
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /******************查询快捷数据信息*****************/
|
|
|
- quickReplyInfo() {
|
|
|
- let obj = {
|
|
|
- headers: {
|
|
|
- apiToken: this.$md5("userwords" + "customer-service" + "index" + this.time[0]+ "service"),
|
|
|
- userToken: this.token
|
|
|
- }
|
|
|
- };
|
|
|
- this.get("api" + this.$ports.FastReply.userWords, obj).then(res => {
|
|
|
- if (res.data.code ==1) {
|
|
|
- this.FastReply = res.data.data;
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- /******************获取快捷语文字******************/
|
|
|
- getLanguage(e){
|
|
|
- //console.log(e);
|
|
|
- this.inputValue =this.inputValue +e;
|
|
|
- },
|
|
|
-
|
|
|
- /*****************表情包输入框赋值******************/
|
|
|
- frceCenterClick(text) {
|
|
|
- this.inputValue = this.inputValue + "#" + text + "/";
|
|
|
- //console.log(this.inputValue);
|
|
|
- },
|
|
|
-
|
|
|
- /******************* 快捷语库开关 ******************/
|
|
|
- FastReplySwitchClick(num) {
|
|
|
- this.FastReplySwitch = num;
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- /*****************获取当前聊天用户信息****************/
|
|
|
- get_user_info(type){
|
|
|
- if(type.length > 0 ){
|
|
|
- this. session_user_info = {};
|
|
|
- this.session_user_info = type[this.dataIndex];
|
|
|
- // console.log(this.session_user_info);
|
|
|
- }else{
|
|
|
- this.session_user_info = '';
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /********************获取配置信息********************/
|
|
|
- get_config_info(){
|
|
|
- let obj = {
|
|
|
- headers: {
|
|
|
- apiToken: this.$md5("minround" + "customer-service" + "evaluate" + this.time[0]+ "index"),
|
|
|
- userToken: this.token
|
|
|
- }
|
|
|
- };
|
|
|
- this.get("api/" + this.$ports.minRound, obj).then(res => {
|
|
|
- if (res.data.code ==1) {
|
|
|
- this.trigger_condition = res.data.data.systemconfig_data;
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- /***********发送消息或接收消息后自动滚动高度*************/
|
|
|
- automaticRolling(){
|
|
|
- this.$nextTick(() => {
|
|
|
- let msg = document.getElementById('chat_box') // 获取对象
|
|
|
- msg.scrollTop = msg.scrollHeight // 滚动高度
|
|
|
-
|
|
|
- })
|
|
|
- },
|
|
|
-
|
|
|
- /**************获取敏感词**************** */
|
|
|
- getSensitive() {
|
|
|
- let obj = {
|
|
|
- headers: {
|
|
|
- "apiToken": this.$md5('sensitivewords' + "customer-service"+'index'+this.time[0]+'index'),
|
|
|
- 'userToken': this.token
|
|
|
- }
|
|
|
- };
|
|
|
- this.post('api'+this.$ports.sensitiveWords, '', obj).then(res => {
|
|
|
- if (res.data.code == 1) {
|
|
|
- res.data.data.serverSensitive.forEach(res => {
|
|
|
- this.sensitive.push(res.sensitivewords_word)
|
|
|
- })
|
|
|
- }
|
|
|
- })
|
|
|
- },
|
|
|
-
|
|
|
- },
|
|
|
- /**
|
|
|
- * 挂载前执行
|
|
|
- */
|
|
|
- mounted() {
|
|
|
- //获取vuex数据
|
|
|
- let getters = this.$store.getters
|
|
|
- this.sessionList = getters.get_session ? getters.get_session :[] ;
|
|
|
- this.offlineList = getters.get_offline ? getters.get_offline :[] ;
|
|
|
- this.token =getters.get_user_info.token ;
|
|
|
- this.user_info = getters.get_user_info;
|
|
|
- this.time =JSON.parse(sessionStorage.getItem("time"));
|
|
|
- let _this = this;
|
|
|
- this.get_config_info();
|
|
|
- if(this.$store.getters.get_is_init){
|
|
|
- // this.$websocket.onmessage = this.;
|
|
|
- _this.websocketsend(JSON.stringify({
|
|
|
- type:'init',
|
|
|
- data:{
|
|
|
- uid:'KF'+_this.user_info.id,
|
|
|
- group:_this.user_info.group_id,
|
|
|
- token: this.token,
|
|
|
- name:_this.user_info.user_name,
|
|
|
- avatar:_this.user_info.user_avatar,
|
|
|
- }
|
|
|
- }));
|
|
|
- this.$store.dispatch("SET_IS_INIT",false);
|
|
|
- }
|
|
|
- //获取客服快捷语
|
|
|
- this.quickReplyInfo();
|
|
|
- //获取敏感词
|
|
|
- this.getSensitive();
|
|
|
- this.frceArr = this.$frce;
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 事件监听
|
|
|
- */
|
|
|
- watch:{
|
|
|
- get_session_message(e){
|
|
|
- this.chatMessage(e)
|
|
|
- },
|
|
|
-
|
|
|
- /*****************评价按钮显示隐藏处理*****************/
|
|
|
- get_is_eva_btn(data){
|
|
|
- if(this.sessionType != 2){
|
|
|
- if(this.data.length > this.trigger_condition){
|
|
|
- if(!this.data[this.dataIndex].isEva){
|
|
|
- // this.is_eva_btn = true;
|
|
|
- // }else{
|
|
|
- this.data[this.dataIndex].isEva = true;
|
|
|
- this.is_eva_btn = false;
|
|
|
- }
|
|
|
- }else{
|
|
|
- this.is_eva_btn = true;
|
|
|
- }
|
|
|
- }else{
|
|
|
- this.is_eva_btn = true;
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 计算属性
|
|
|
- */
|
|
|
- computed:{
|
|
|
- get_session_message(){
|
|
|
- return this.$store.getters.get_session_message;
|
|
|
- },
|
|
|
- /****************判断是否可以点击评价*****************/
|
|
|
- get_is_eva_btn(){
|
|
|
- return this.data;
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- components: {
|
|
|
- leftNav,
|
|
|
- hader,
|
|
|
- messageCenter
|
|
|
- }
|
|
|
-};
|
|
|
+ import "@/css/index.css";
|
|
|
+ import leftNav from "@/components/leftNav";
|
|
|
+ import hader from "@/components/hader";
|
|
|
+ import messageCenter from "@/components/messageCenter";
|
|
|
+
|
|
|
+ export default {
|
|
|
+ name: "TheCurrentSession",
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ /***********************************/
|
|
|
+ inputValue: "", //输入框内容
|
|
|
+ isFrce: false, //表情包开关
|
|
|
+ frceArr: [], //表情包数组
|
|
|
+ data: [], //当前对话数据
|
|
|
+ dataIndex:0,//定位当前会话,默认是0
|
|
|
+ FastReply: "", //快捷回复
|
|
|
+ FastReplySwitch: "one", //快捷回复开关
|
|
|
+ user_info:'',//用户信息
|
|
|
+ token: "",
|
|
|
+ time: "",
|
|
|
+ sessionList:[],//会话列表
|
|
|
+ offlineList:[],//离线列表
|
|
|
+ transferList:[],//转接列表
|
|
|
+ sessionType:1,//选择列表状态默认未1(1是会话中,2是离线)
|
|
|
+ lineUp:[],//排队列表
|
|
|
+ conversationId:'',//会话工单
|
|
|
+ sessionName:'',//当前会话用户名字
|
|
|
+ session_user_info:{},//当前会话用户信息
|
|
|
+ img_http:'http://kfadmin.bocai186.com',//图片路径域
|
|
|
+ //img_http:'http://192.168.2.186:8090',//图片路径域
|
|
|
+ fit:'scale-down',//图片渲染样式
|
|
|
+ is_eva_btn:true,//
|
|
|
+ trigger_condition:0,//评价触发条件
|
|
|
+ webTime:'',//客服会话时间
|
|
|
+ session_marked:'',//客服当前会话标记
|
|
|
+ sensitive:[],//敏感词数据
|
|
|
+ };
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ */
|
|
|
+ methods: {
|
|
|
+ /************回车提交************/
|
|
|
+ listenEnter(event){
|
|
|
+ if (event.keyCode === 13) {
|
|
|
+ this.inputValue = this.inputValue.replace(/\s/g,'')
|
|
|
+ // this.inputValue = this.inputValue.replace(/\n /g,'')
|
|
|
+ this.sendMessage(); // 发送文本
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /************ctrl+center 换行***********/
|
|
|
+ lineFeed(){
|
|
|
+ this.inputValue = this.inputValue + '\n'
|
|
|
+ },
|
|
|
+ /******************消息数据接收********************/
|
|
|
+ chatMessage(redata){
|
|
|
+ // console.log('列表',this.sessionList)
|
|
|
+ if(redata.type == "pong" ) return
|
|
|
+ console.log('消息',redata)
|
|
|
+ // 用户接入数据
|
|
|
+ if(redata.message_type == "connect"){
|
|
|
+ this.conversationId = redata.data.conversationId;
|
|
|
+ redata.data.user_info.conversationId = redata.data.conversationId;
|
|
|
+ let isTrue = true;
|
|
|
+ //匹配是否是离线用户上线
|
|
|
+ if(this.offlineList.length > 0){
|
|
|
+ for(let i = 0; i < this.offlineList.length ; i++){
|
|
|
+ //匹配离线列表是否有这个用户
|
|
|
+ if(this.offlineList[i].id == redata.data.user_info.id ){
|
|
|
+ //匹配离线列表是否存会话工单未结束
|
|
|
+ if(this.offlineList[i].conversationId == redata.data.conversationId){
|
|
|
+ //工单号未结束的数据处理
|
|
|
+ if(this.sessionType == 2 && i == this.dataIndex){
|
|
|
+ this.data = [];
|
|
|
+ this.data = this.offlineList[i].data;
|
|
|
+ }
|
|
|
+ redata.data.user_info.data = this.offlineList[i].data
|
|
|
+ }else{
|
|
|
+ //工单号已结束数据处理
|
|
|
+ if(this.dataIndex == 0 && this.sessionList.length == 0){
|
|
|
+ this.sessionName = redata.data.user_info.name;
|
|
|
+ this.data = [];
|
|
|
+ }
|
|
|
+ redata.data.user_info.data = [];
|
|
|
+ }
|
|
|
+ //将离线状态用户删除
|
|
|
+ this.offlineList.splice(i,1);
|
|
|
+ this.$store.dispatch("SET_OFFLINE",this.offlineList);
|
|
|
+ this.get_user_info(this.offlineList);
|
|
|
+ isTrue = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ this.sessionType = 1;
|
|
|
+ this.sessionName = '';
|
|
|
+ this.data = [];
|
|
|
+ }
|
|
|
+ if(isTrue){
|
|
|
+ if(this.dataIndex == 0 && this.sessionList.length == 0){
|
|
|
+ this.sessionName = redata.data.user_info.name;
|
|
|
+ this.data = [];
|
|
|
+ }
|
|
|
+ redata.data.user_info.data = [];
|
|
|
+ }
|
|
|
+ redata.data.user_info.intime = this.time[1];
|
|
|
+ redata.data.user_info.num = 0;
|
|
|
+ this.sessionList.push(redata.data.user_info);
|
|
|
+ this.get_user_info(this.sessionList);
|
|
|
+ //将数据储存到vuex里面
|
|
|
+ this.$store.dispatch("SET_SESSION",this.sessionList);
|
|
|
+ // this.$store.getters.getLimit
|
|
|
+ }
|
|
|
+
|
|
|
+ //用户离线后会话窗口切换
|
|
|
+ if(redata.message_type == "userClose"){
|
|
|
+ for(let i = 0 ; i < this.sessionList.length; i++){
|
|
|
+ //匹配会话中离线用户
|
|
|
+ if(this.sessionList[i].id == redata.data.id ){
|
|
|
+ //把数据添加到离线列表
|
|
|
+ this.offlineList.push(this.sessionList[i]);
|
|
|
+ this.$store.dispatch("SET_OFFLINE",this.offlineList);
|
|
|
+ //用户选中状态会话中处理
|
|
|
+ if(this.sessionType == 1){
|
|
|
+ //判断会话中列表长度
|
|
|
+ if(this.sessionList.length > 1){
|
|
|
+ //删除会话列表离线用户
|
|
|
+ this.sessionList.splice(i,1);
|
|
|
+ this.$store.dispatch("SET_SESSION",this.sessionList);
|
|
|
+ //获取会话中列表第一个会话消息
|
|
|
+ this.dataIndex = 0;
|
|
|
+ this.sessionName = this.sessionList[0].name;
|
|
|
+ this.data = [];
|
|
|
+ this.data = this.sessionList[0].data;
|
|
|
+ }else{
|
|
|
+ this.sessionType = 2;
|
|
|
+ this.dataIndex = 0;
|
|
|
+ // if(this.offlineList.length >0){
|
|
|
+ // }else{}
|
|
|
+ this.sessionName =this.offlineList[0].name;
|
|
|
+ this.data = this.offlineList[0].data;
|
|
|
+ //删除会话列表离线用户
|
|
|
+ this.sessionList.splice(i,1);
|
|
|
+ this.$store.dispatch("SET_SESSION",this.sessionList);
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ //删除会话列表离线用户
|
|
|
+ this.sessionList.splice(i,1);
|
|
|
+ this.$store.dispatch("SET_SESSION",this.sessionList);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.get_user_info(this.sessionList);
|
|
|
+ }
|
|
|
+
|
|
|
+ //用户断开链接会话窗口切换
|
|
|
+ if(redata.message_type == "delUser"){
|
|
|
+ let isTrue = true;
|
|
|
+ //会话中列表匹配
|
|
|
+ for(let i = 0 ; i < this.sessionList.length; i++){
|
|
|
+ //判断会话中列表是否结束会话
|
|
|
+ if(this.sessionList[i].id == redata.data.id){
|
|
|
+ //删除会话列表断线关闭的用户信息
|
|
|
+ this.sessionList.splice(i,1);
|
|
|
+ this.$store.dispatch("SET_SESSION",this.sessionList);
|
|
|
+ if(this.sessionType == 1){
|
|
|
+ //处理会话显现状态
|
|
|
+ if(this.dataIndex == i){
|
|
|
+ if(this.sessionList.length >1){
|
|
|
+ this.sessionName = this.sessionList[0].name;
|
|
|
+ this.data = this.sessionList[0].data;
|
|
|
+ this.get_user_info(this.sessionList);
|
|
|
+ }else{
|
|
|
+ this.sessionName = '';
|
|
|
+ this.data = [];
|
|
|
+ this.get_user_info(this.offlineList);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ isTrue = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //离线列表匹配
|
|
|
+ if(isTrue){
|
|
|
+ for(let i = 0 ; i < this.offlineList.length; i++){
|
|
|
+ //判断离线列表是否结束会话
|
|
|
+ if(this.offlineList[i].id == redata.data.id){
|
|
|
+ console.log('离线列');
|
|
|
+ //删除离线列表中断线关闭的用户信息
|
|
|
+ this.offlineList.splice(i,1);
|
|
|
+ this.$store.dispatch("SET_OFFLINE",this.offlineList);
|
|
|
+ if(this.sessionType == 2){
|
|
|
+ if(this.dataIndex == i){
|
|
|
+ console.log('别乱动 大于1','来了吗');
|
|
|
+ if(this.offlineList.length > 1){
|
|
|
+ this.data = this.offlineList[0].data;
|
|
|
+ this.sessionName = this.offlineList[0].name;
|
|
|
+ this.get_user_info(this.offlineList);
|
|
|
+ }else{
|
|
|
+ console.log('别乱动 小于1','来了吗');
|
|
|
+ this.data = [];
|
|
|
+ this.sessionName = '';
|
|
|
+ this.get_user_info(this.sessionList);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //接收用户消息数据
|
|
|
+ if(redata.message_type == "chatMessage"){
|
|
|
+ let dataIndex = 0;
|
|
|
+ //匹配是那个用户回的消息
|
|
|
+ for(let i = 0 ; i < this.sessionList.length ; i++){
|
|
|
+ if(this.sessionList[i].id == redata.data.id ){
|
|
|
+ dataIndex = i;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //获取当前回复消息对象
|
|
|
+ let chatList = this.sessionList[dataIndex]
|
|
|
+ redata.data.type = 'user';
|
|
|
+ redata.data.content = JSON.parse(redata.data.content);
|
|
|
+ //这个地方转
|
|
|
+
|
|
|
+ redata.data.content.text = this.turnFace(redata.data.content.text);
|
|
|
+ //更新会话时间
|
|
|
+ this.$set(chatList,'intime',redata.data.time);
|
|
|
+
|
|
|
+ //更新会话列表中最新回复消息
|
|
|
+ if(redata.data.content.text){
|
|
|
+ this.$set(chatList,'text',redata.data.content.text)
|
|
|
+ }
|
|
|
+
|
|
|
+ //将消息添加对应的会话列表中
|
|
|
+ chatList.data.push(redata.data);
|
|
|
+ //判断是否是当前对话信息
|
|
|
+ if(dataIndex == this.dataIndex){
|
|
|
+ this.data =[];
|
|
|
+ this.data = chatList.data;
|
|
|
+ }else{
|
|
|
+ let num = chatList.num;
|
|
|
+ //console.log(chatList.num);
|
|
|
+ this.$set(chatList,'num',num+1)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //接收系统操作信息状态在线客服列表
|
|
|
+ if(redata.message_type == "onlinekfs"){
|
|
|
+ this.transferList = [];
|
|
|
+ this.transferList = this.transferList.concat(redata.data);
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ if(redata.message_type == "webTime"){
|
|
|
+ // this.webTime = redata.data.webTime
|
|
|
+ this.$set(this.data[this.session_marked],'time',redata.data.webTime);
|
|
|
+ }
|
|
|
+
|
|
|
+ //客服手动转接用户成功
|
|
|
+ if(redata.message_type == "trunconnect"){
|
|
|
+ this.sessionList.splice(this.dataIndex,1);
|
|
|
+ this.$message({
|
|
|
+ message: '转接用户成功...',
|
|
|
+ type: 'success'
|
|
|
+ });
|
|
|
+ if(this.sessionList.length >1 ){
|
|
|
+ this.dataIndex =0;
|
|
|
+ // this.data = []
|
|
|
+
|
|
|
+ }else{
|
|
|
+ this.data = [];
|
|
|
+ this.sessionName ='';
|
|
|
+ // if(this.offlineList.length >0){
|
|
|
+ // this.data = [];
|
|
|
+ // this.sessionName ='';
|
|
|
+ // }else{
|
|
|
+ // this.data = [];
|
|
|
+ // this.sessionName ='';
|
|
|
+ // }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.automaticRolling();
|
|
|
+ },
|
|
|
+ /******************文字信息转表情******************/
|
|
|
+ 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.$frce.length ; i++){
|
|
|
+ let expText = e.slice(1,e.length-1);
|
|
|
+ if(expText == this.$frce[i]){
|
|
|
+ imgsrc = '<img class="hover" src="'+require(`@/assets/img/${i}.gif`)+'"/>'
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ data = data.replace(new RegExp(`\\#\\[${e.substring(2,e.length-2)}\\]\\/`,'g'),imgsrc);
|
|
|
+ })
|
|
|
+ return data;
|
|
|
+ },
|
|
|
+
|
|
|
+ /*********************图片发送*********************/
|
|
|
+ uploadIMG(e) {
|
|
|
+ //console.log(e);
|
|
|
+ let self = this;
|
|
|
+ let files = e.target.files || e.dataTransfer.files;
|
|
|
+ if (!files.length) return;
|
|
|
+ let picavalue = files[0];
|
|
|
+ //console.log(picavalue);
|
|
|
+ if (picavalue.size / 1000 > 20000) {
|
|
|
+ this.$message({
|
|
|
+ message: "图片过大不支持上传",
|
|
|
+ type: "warning"
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.$public.imgPreview(picavalue, function(imgSrc,formData) {
|
|
|
+ // 数据结构请求
|
|
|
+ self.post('api/'+self.$ports.uploadImg,formData).then(res=>{
|
|
|
+ //console.log(res.data.data.src)
|
|
|
+ if(res.data.code == 1){
|
|
|
+ let isFirst = true;
|
|
|
+ //判断客服是否发送的第一句话
|
|
|
+ if(self.data.length >0){
|
|
|
+ for(let i = 0 ; i < self.data.length ; i++ ){
|
|
|
+ if(self.data[i].type == 'service' ){
|
|
|
+ isFirst =false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let obj = {
|
|
|
+ text:'',
|
|
|
+ img:res.data.data.src,
|
|
|
+ type:false,
|
|
|
+ };
|
|
|
+ let chatList = self.sessionList[self.dataIndex];
|
|
|
+ chatList.data.push({type:'service', content:obj ,time:self.time[1]});
|
|
|
+ self.data = [];
|
|
|
+ self.data = chatList.data;
|
|
|
+ let type ='chatMessage';
|
|
|
+ let data = {
|
|
|
+ from_name:self.user_info.user_name,//发送者
|
|
|
+ from_avatar:self.user_info.avatar,//发送者头像
|
|
|
+ from_id:"KF"+self.user_info.id,//发送者id
|
|
|
+ content:JSON.stringify(obj),
|
|
|
+ to_id: self.sessionList[self.dataIndex].id,
|
|
|
+ to_name:self.sessionList[self.dataIndex].name,
|
|
|
+ conversationId:self.sessionList[self.dataIndex].conversationId,
|
|
|
+ isFirst:isFirst,//是否是第一句话
|
|
|
+ sensitiveNumber:0,//敏感词次数
|
|
|
+ }
|
|
|
+ self.websocketsend(JSON.stringify({type,data}))
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ })
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /*****************转接会话用户确认******************/
|
|
|
+ transfer(e){
|
|
|
+
|
|
|
+ if(this.sessionList.length > 0){
|
|
|
+ this.$confirm('此操作将当前用户转出, 是否继续?', '温馨提示!', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning'
|
|
|
+ }).then(() => {
|
|
|
+ let type ="changeOtherhKeFu";
|
|
|
+ let data={
|
|
|
+ conversationId:this.sessionType == 1 ? this.sessionList[this.dataIndex].conversationId : this.offlineList[this.dataIndex].conversationId,
|
|
|
+ togroup:this.transferList[e].groupid,
|
|
|
+ fromgroup:this.user_info.group_id,
|
|
|
+ toukfuid:this.transferList[e].kfuid ,
|
|
|
+ fromkfuid:"KF"+this.user_info.id,
|
|
|
+ uid:this.sessionType == 1 ? this.sessionList[this.dataIndex].id : this.offlineList[this.dataIndex].id,
|
|
|
+ word:'',
|
|
|
+ }
|
|
|
+ //console.log({type,data});
|
|
|
+ this.websocketsend(JSON.stringify({type,data}))
|
|
|
+ }).catch(() => {
|
|
|
+
|
|
|
+ })
|
|
|
+ }else{
|
|
|
+ this.$message({
|
|
|
+ message: '亲!您没有和用户会话怎么能转接呢。',
|
|
|
+ type: 'warning'
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+ /******************获取客服人员列表*****************/
|
|
|
+ getServiceList(){
|
|
|
+ //console.log(12313);
|
|
|
+ this.websocketsend(JSON.stringify({"type":"getkfonlines"}))
|
|
|
+ },
|
|
|
+
|
|
|
+ /*****************切换用户会话对象******************/
|
|
|
+ chooseDialogue(type,index){
|
|
|
+ let data =[];
|
|
|
+ this.sessionType = type;
|
|
|
+ this.dataIndex = index;
|
|
|
+ if(type == 1){
|
|
|
+ data = this.sessionList[index].data;
|
|
|
+ this.session_user_info = this.sessionList[index];
|
|
|
+ this.$set(this.sessionList[index],'num',0);
|
|
|
+ this.sessionName = this.sessionList[index].name
|
|
|
+ }else if(type == 2){
|
|
|
+ data = this.offlineList[index].data;
|
|
|
+ this.sessionName = this.offlineList[index].name;
|
|
|
+ this.session_user_info = this.offlineList[index];
|
|
|
+ }
|
|
|
+ this.data = data;
|
|
|
+ },
|
|
|
+
|
|
|
+ /***************关闭当前和用户聊天对话***************/
|
|
|
+ open(){
|
|
|
+ let _this =this;
|
|
|
+ if(this.sessionType == 1){
|
|
|
+ if(this.sessionList.length < 1 )return
|
|
|
+ }else{
|
|
|
+ if(this.offlineList.length < 1)return
|
|
|
+ }
|
|
|
+ this.$confirm('此操作将关闭和当前用户通话, 是否继续?', '温馨提示!', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning'
|
|
|
+ }).then(() => {
|
|
|
+ let to_id = this.sessionType == 1 ? this.sessionList[this.dataIndex].id :this.offlineList[this.dataIndex].id;
|
|
|
+ let conversationId = this.sessionType == 1 ? this.sessionList[this.dataIndex].conversationId :this.offlineList[this.dataIndex].conversationId;
|
|
|
+ let data = {
|
|
|
+ "type":"kfCloseUser",
|
|
|
+ data:{
|
|
|
+ to_id,
|
|
|
+ kf_id:"KF"+_this.user_info.id,
|
|
|
+ group_id:_this.user_info.group_id,
|
|
|
+ conversationId:conversationId,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(this.sessionType == 1){
|
|
|
+ this.sessionList.splice(this.dataIndex,1);
|
|
|
+ if(this.sessionList.length> 0){
|
|
|
+ this.data = this.sessionList[0];
|
|
|
+ this.sessionName = this.sessionList[0].name;
|
|
|
+ }else{
|
|
|
+ this.data = [];
|
|
|
+ this.sessionName = '';
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ this.offlineList.splice(this.dataIndex,1);
|
|
|
+ this.data = [];
|
|
|
+ this.sessionName = '';
|
|
|
+ }
|
|
|
+
|
|
|
+ this.websocketsend(JSON.stringify(data))
|
|
|
+ }).catch(() => {
|
|
|
+ // this.$message({
|
|
|
+ // type: 'info',
|
|
|
+ // message: '已取消删除'
|
|
|
+ // });
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ /*****************数据发送方法调用******************/
|
|
|
+ websocketsend(Data) {
|
|
|
+ this.$websocket.send(Data);
|
|
|
+ this.automaticRolling();
|
|
|
+ },
|
|
|
+
|
|
|
+ /*********************发送消息*********************/
|
|
|
+ sendMessage(){
|
|
|
+ console.log();
|
|
|
+ if(!this.inputValue) return
|
|
|
+ if(this.sessionList.length == 0) {
|
|
|
+ this.$message({
|
|
|
+ message: '只能给在线用户发送消息哦...',
|
|
|
+ type: 'warning'
|
|
|
+ });
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ // if(this.offlineList.length <= 0 ) return
|
|
|
+ let isFirst = true,sensitiveNumber=0;
|
|
|
+ this.isFrce = false;
|
|
|
+ //判断客服是否发送的第一句话
|
|
|
+ if(this.data.length >0){
|
|
|
+ for(let i = 0 ; i < this.data.length ; i++ ){
|
|
|
+ if(this.data[i].type == 'service' ){
|
|
|
+ isFirst =false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //判断客服敏感词报警次数
|
|
|
+ let obj = {
|
|
|
+ text: this.inputValue,
|
|
|
+ img:'',
|
|
|
+ type:false,
|
|
|
+ }
|
|
|
+ let type ='chatMessage';
|
|
|
+ let data = {
|
|
|
+ from_name:this.user_info.user_name,//发送者
|
|
|
+ from_avatar:this.user_info.avatar,//发送者头像
|
|
|
+ from_id:"KF"+this.user_info.id,//发送者id
|
|
|
+ content:JSON.stringify(obj),
|
|
|
+ to_id: this.sessionList[this.dataIndex].id,
|
|
|
+ to_name:this.sessionList[this.dataIndex].name,
|
|
|
+ conversationId:this.sessionList[this.dataIndex].conversationId,
|
|
|
+ isFirst:isFirst,//是否是第一句话
|
|
|
+ sensitiveNumber:sensitiveNumber,//敏感词次数
|
|
|
+ }
|
|
|
+ let chatList = this.sessionList[this.dataIndex];
|
|
|
+ //检测发送信息是否含有敏感词
|
|
|
+ let sensitive_data= this.$public.shieldingKeyword(this.turnFace(this.inputValue),this.sensitive);
|
|
|
+
|
|
|
+ //有敏感词提示并且禁止发送
|
|
|
+ if(sensitive_data.num == 0 ){
|
|
|
+ // 本地储存
|
|
|
+ chatList.data.push({type:'service', content:{
|
|
|
+ text:this.turnFace(this.inputValue),
|
|
|
+ img:'',
|
|
|
+ type:false,
|
|
|
+ } ,time:this.time[1]});
|
|
|
+
|
|
|
+ this.data = [];
|
|
|
+ //标记当前会话位置
|
|
|
+ this.session_marked = chatList.data.length -1;
|
|
|
+ this.data = chatList.data;
|
|
|
+ this.websocketsend(JSON.stringify({type,data}))
|
|
|
+ this.inputValue = '';
|
|
|
+ }else{
|
|
|
+ this.$message({
|
|
|
+ message: '敏感词'+sensitive_data.text,
|
|
|
+ type: 'warning'
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+ /******************开启或关闭表情包******************/
|
|
|
+ frceClick() {
|
|
|
+ this.isFrce = !this.isFrce;
|
|
|
+ },
|
|
|
+
|
|
|
+ /*******************发送评价指令*******************/
|
|
|
+ evaluation(){
|
|
|
+ console.log(this.sessionList[this.dataIndex]);
|
|
|
+ if(!this.is_eva_btn && this.sessionType == 1){
|
|
|
+ this.$message({
|
|
|
+ message: '评价指令已发送',
|
|
|
+ type: 'success'
|
|
|
+ });
|
|
|
+ let type = 'getEvaluate';
|
|
|
+ let data = {
|
|
|
+ conversationId:this.sessionList[this.dataIndex].conversationId,
|
|
|
+ to_id:this.sessionList[this.dataIndex].id,
|
|
|
+ }
|
|
|
+ this.websocketsend(JSON.stringify({type,data}));
|
|
|
+ this.is_eva_btn = true;
|
|
|
+ }else if(this.sessionType == 2){
|
|
|
+ this.$message.error('用户已离线指令无法发送');
|
|
|
+ }else {
|
|
|
+ this.$message.error('评价指令无法发送');
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /******************查询快捷数据信息*****************/
|
|
|
+ quickReplyInfo() {
|
|
|
+ let obj = {
|
|
|
+ headers: {
|
|
|
+ apiToken: this.$md5("userwords" + "customer-service" + "index" + this.time[0]+ "service"),
|
|
|
+ userToken: this.token
|
|
|
+ }
|
|
|
+ };
|
|
|
+ this.get("api" + this.$ports.FastReply.userWords, obj).then(res => {
|
|
|
+ if (res.data.code ==1) {
|
|
|
+ this.FastReply = res.data.data;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ /******************获取快捷语文字******************/
|
|
|
+ getLanguage(e){
|
|
|
+ //console.log(e);
|
|
|
+ this.inputValue =this.inputValue +e;
|
|
|
+ },
|
|
|
+
|
|
|
+ /*****************表情包输入框赋值******************/
|
|
|
+ frceCenterClick(text) {
|
|
|
+ this.inputValue = this.inputValue + "#" + text + "/";
|
|
|
+ //console.log(this.inputValue);
|
|
|
+ },
|
|
|
+
|
|
|
+ /******************* 快捷语库开关 ******************/
|
|
|
+ FastReplySwitchClick(num) {
|
|
|
+ this.FastReplySwitch = num;
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+ /*****************获取当前聊天用户信息****************/
|
|
|
+ get_user_info(type){
|
|
|
+ if(type.length > 0 ){
|
|
|
+ this. session_user_info = {};
|
|
|
+ this.session_user_info = type[this.dataIndex];
|
|
|
+ // console.log(this.session_user_info);
|
|
|
+ }else{
|
|
|
+ this.session_user_info = '';
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /********************获取配置信息********************/
|
|
|
+ get_config_info(){
|
|
|
+ let obj = {
|
|
|
+ headers: {
|
|
|
+ apiToken: this.$md5("minround" + "customer-service" + "evaluate" + this.time[0]+ "index"),
|
|
|
+ userToken: this.token
|
|
|
+ }
|
|
|
+ };
|
|
|
+ this.get("api/" + this.$ports.minRound, obj).then(res => {
|
|
|
+ if (res.data.code ==1) {
|
|
|
+ this.trigger_condition = res.data.data.systemconfig_data;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ /***********发送消息或接收消息后自动滚动高度*************/
|
|
|
+ automaticRolling(){
|
|
|
+ this.$nextTick(() => {
|
|
|
+ let msg = document.getElementById('chat_box') // 获取对象
|
|
|
+ msg.scrollTop = msg.scrollHeight // 滚动高度
|
|
|
+
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ /**************获取敏感词**************** */
|
|
|
+ getSensitive() {
|
|
|
+ let obj = {
|
|
|
+ headers: {
|
|
|
+ "apiToken": this.$md5('sensitivewords' + "customer-service"+'index'+this.time[0]+'index'),
|
|
|
+ 'userToken': this.token
|
|
|
+ }
|
|
|
+ };
|
|
|
+ this.post('api'+this.$ports.sensitiveWords, '', obj).then(res => {
|
|
|
+ if (res.data.code == 1) {
|
|
|
+ res.data.data.serverSensitive.forEach(res => {
|
|
|
+ this.sensitive.push(res.sensitivewords_word)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 挂载前执行
|
|
|
+ */
|
|
|
+ mounted() {
|
|
|
+ //获取vuex数据
|
|
|
+ let getters = this.$store.getters
|
|
|
+ this.sessionList = getters.get_session ? getters.get_session :[] ;
|
|
|
+ this.offlineList = getters.get_offline ? getters.get_offline :[] ;
|
|
|
+ this.token =getters.get_user_info.token ;
|
|
|
+ this.user_info = getters.get_user_info;
|
|
|
+ this.time =JSON.parse(sessionStorage.getItem("time"));
|
|
|
+ let _this = this;
|
|
|
+ this.get_config_info();
|
|
|
+ if(this.$store.getters.get_is_init){
|
|
|
+ // this.$websocket.onmessage = this.;
|
|
|
+ _this.websocketsend(JSON.stringify({
|
|
|
+ type:'init',
|
|
|
+ data:{
|
|
|
+ uid:'KF'+_this.user_info.id,
|
|
|
+ group:_this.user_info.group_id,
|
|
|
+ token: this.token,
|
|
|
+ name:_this.user_info.user_name,
|
|
|
+ avatar:_this.user_info.user_avatar,
|
|
|
+ }
|
|
|
+ }));
|
|
|
+ this.$store.dispatch("SET_IS_INIT",false);
|
|
|
+ }
|
|
|
+ //获取客服快捷语
|
|
|
+ this.quickReplyInfo();
|
|
|
+ //获取敏感词
|
|
|
+ this.getSensitive();
|
|
|
+ this.frceArr = this.$frce;
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 事件监听
|
|
|
+ */
|
|
|
+ watch:{
|
|
|
+ get_session_message(e){
|
|
|
+ this.chatMessage(e)
|
|
|
+ },
|
|
|
+
|
|
|
+ /*****************评价按钮显示隐藏处理*****************/
|
|
|
+ get_is_eva_btn(data){
|
|
|
+ if(this.sessionType != 2){
|
|
|
+ if(this.data.length > this.trigger_condition){
|
|
|
+ if(!this.data[this.dataIndex].isEva){
|
|
|
+ // this.is_eva_btn = true;
|
|
|
+ // }else{
|
|
|
+ this.data[this.dataIndex].isEva = true;
|
|
|
+ this.is_eva_btn = false;
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ this.is_eva_btn = true;
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ this.is_eva_btn = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算属性
|
|
|
+ */
|
|
|
+ computed:{
|
|
|
+ get_session_message(){
|
|
|
+ return this.$store.getters.get_session_message;
|
|
|
+ },
|
|
|
+ /****************判断是否可以点击评价*****************/
|
|
|
+ get_is_eva_btn(){
|
|
|
+ return this.data;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ components: {
|
|
|
+ leftNav,
|
|
|
+ hader,
|
|
|
+ messageCenter
|
|
|
+ }
|
|
|
+ };
|
|
|
</script>
|
|
|
|
|
|
<style>
|
|
|
-.el-icon-arrow-right:before {
|
|
|
- content: "\E791";
|
|
|
- color: #ccc;
|
|
|
-}
|
|
|
-.session_choose{
|
|
|
- background:#F6F8FF;
|
|
|
-}
|
|
|
-.session_style:hover {
|
|
|
- /* background:#F6F8FF; */
|
|
|
- background:#ECF4FF ;
|
|
|
- cursor:pointer;
|
|
|
-}
|
|
|
-.sessionList {
|
|
|
- width: 21vw;
|
|
|
- background: #fff;
|
|
|
-}
|
|
|
-.markNumber{
|
|
|
- display: inline-block;
|
|
|
- width:20px;
|
|
|
- height:20px;
|
|
|
- border-radius: 50%;
|
|
|
- background:#f60;
|
|
|
- font-size:12px;
|
|
|
- color:#fff;
|
|
|
- text-align: center;
|
|
|
- line-height: 20px;
|
|
|
-}
|
|
|
-.el-collapse-item__header {
|
|
|
- position: relative;
|
|
|
- font-size: 14px;
|
|
|
- font-weight:bold;
|
|
|
- color:#666;
|
|
|
- font-family:PingFang SC;
|
|
|
- padding-left: 32px;
|
|
|
- height: 49px;
|
|
|
- justify-content: space-between;
|
|
|
- padding-right: 10px;
|
|
|
-}
|
|
|
-.el-collapse-item__header.is-active {
|
|
|
- border-bottom: 1px solid #d5e5ff;
|
|
|
-}
|
|
|
-.el-collapse-item__header {
|
|
|
- border-bottom: 1px solid #d5e5ff;
|
|
|
-}
|
|
|
-.el-icon-arrow-right {
|
|
|
- position: absolute;
|
|
|
- left: 10px;
|
|
|
- top: auto;
|
|
|
-}
|
|
|
-.sessionList_span {
|
|
|
- color: #999;
|
|
|
-}
|
|
|
-.user {
|
|
|
- padding: 10px;
|
|
|
-}
|
|
|
-.evaluation{
|
|
|
- font-size: 24px;
|
|
|
- color: #969696;
|
|
|
-}
|
|
|
-.el-collapse-item__content {
|
|
|
- padding-bottom: 0;
|
|
|
-}
|
|
|
-.chat {
|
|
|
- width: 29vw;
|
|
|
- height: 93vh;
|
|
|
- border: 1px solid #d5e5ff;
|
|
|
- border-top: none;
|
|
|
- background: #fff;
|
|
|
-}
|
|
|
-.user_text{
|
|
|
- border: 1px solid #ECF4FF;
|
|
|
- color:#999;
|
|
|
- line-height: 30px;
|
|
|
- width: 80%;
|
|
|
-}
|
|
|
-.user_text:focus {
|
|
|
- outline: none;
|
|
|
-}
|
|
|
-.chatTop {
|
|
|
- height: 50px;
|
|
|
- border-bottom: 1px solid #d5e5ff;
|
|
|
-}
|
|
|
-.chat-box {
|
|
|
- height: 62vh;
|
|
|
- /* background: red; */
|
|
|
- /* padding: 40px 0; */
|
|
|
- border-bottom: 1px solid #d5e5ff;
|
|
|
- overflow-x: hidden;
|
|
|
- overflow-y: auto;
|
|
|
-}
|
|
|
-.chatMsg {
|
|
|
- display: inline-block;
|
|
|
- padding: 10px;
|
|
|
- font-size: 14px;
|
|
|
- max-width: 85%;
|
|
|
- word-wrap: break-word;
|
|
|
-}
|
|
|
-p {
|
|
|
- margin-block-start: 0em;
|
|
|
- margin-block-end: 0em;
|
|
|
- margin-inline-start: 0px;
|
|
|
- margin-inline-end: 0px;
|
|
|
-}
|
|
|
-.frce {
|
|
|
- height: 0.38rem;
|
|
|
- width: 100%;
|
|
|
- padding: 16px 10px;
|
|
|
-}
|
|
|
-.input {
|
|
|
- height: 100px;
|
|
|
- background: #fff;
|
|
|
- resize: none;
|
|
|
- font-size: 14px;
|
|
|
- margin: 0 10px;
|
|
|
- border: none;
|
|
|
- /* border: 1px solid #d5e5ff; */
|
|
|
-}
|
|
|
-.input:focus {
|
|
|
- outline: none;
|
|
|
- border: none;
|
|
|
-}
|
|
|
-.user_info_box{
|
|
|
- margin: 10px 0 ;
|
|
|
-}
|
|
|
-.title_span{
|
|
|
- color:#666;
|
|
|
- font-size:14px;
|
|
|
- font-weight: bold;
|
|
|
-}
|
|
|
-.content_span{
|
|
|
- color:#999;
|
|
|
- font-size:14px;
|
|
|
-}
|
|
|
-.key {
|
|
|
- /* width: 27.8vw; */
|
|
|
- /* position: absolute; */
|
|
|
- bottom: 22px;
|
|
|
- height: 23vh;
|
|
|
- /* background: #409EFF; */
|
|
|
-}
|
|
|
-.msgInputBtn {
|
|
|
- right: 10px;
|
|
|
- bottom: 10px;
|
|
|
- width: 60px;
|
|
|
- height: 30px;
|
|
|
- /* background:#ECF4FF; */
|
|
|
- background:#5399f5;
|
|
|
- margin-right: 10px;
|
|
|
- border-radius: 5px;
|
|
|
- font-size: 14px;
|
|
|
- color: #fff;
|
|
|
- cursor:pointer;
|
|
|
-}
|
|
|
-
|
|
|
-/* .msgInputBtn:hover{
|
|
|
- background:#5399f5;
|
|
|
-} */
|
|
|
-.frceBox {
|
|
|
- position: absolute;
|
|
|
- /* top: 25vw; */
|
|
|
- bottom: 25vh;
|
|
|
- left: 31.5vw;
|
|
|
- width: 28vw;
|
|
|
- height: 25vh;
|
|
|
- background: #fff;
|
|
|
- border: 1px solid #d5e5ff;
|
|
|
- overflow-x: hidden;
|
|
|
- overflow-y: auto;
|
|
|
- z-index: 999999;
|
|
|
-}
|
|
|
-.frceBox p {
|
|
|
- width: 50px;
|
|
|
- height: 50px;
|
|
|
-}
|
|
|
-.FastReply {
|
|
|
- width: 19vw;
|
|
|
- height: 92vh;
|
|
|
- border-right: 1px solid #d5e5ff;
|
|
|
- background: #fff;
|
|
|
-}
|
|
|
-.FastReplyHader {
|
|
|
- height: 50px;
|
|
|
- border-bottom: 1px solid #d5e5ff;
|
|
|
- padding: 0 10px;
|
|
|
- font-size: 14px;
|
|
|
- color: #666;
|
|
|
- font-weight: bold;
|
|
|
-}
|
|
|
-.FastReplySwitch {
|
|
|
- height: 50px;
|
|
|
- border-bottom: 1px solid #d5e5ff;
|
|
|
- color: #666;
|
|
|
- font-size: 14px;
|
|
|
- padding: 0 40px;
|
|
|
-}
|
|
|
-.FastReplySwitch p.active {
|
|
|
- position: relative;
|
|
|
- color:#5399f5;
|
|
|
-}
|
|
|
-.FastReplySwitch p.active::after {
|
|
|
- content: "";
|
|
|
- display: inline-block;
|
|
|
- position: absolute;
|
|
|
- width: 42px;
|
|
|
- height: 2px;
|
|
|
- left: 1px;
|
|
|
- bottom: -15px;
|
|
|
- background: #5399f5;
|
|
|
-}
|
|
|
-ul{
|
|
|
- margin-block-start: 0.4em;
|
|
|
- margin-block-end: 0.4em;
|
|
|
-}
|
|
|
-.cursor_text{
|
|
|
- cursor:pointer;
|
|
|
- margin: 10px 20px;
|
|
|
-}
|
|
|
-.cursor_text:hover{
|
|
|
- color: #d5e5ff;
|
|
|
- background: #f6f8ff;
|
|
|
-}
|
|
|
-.serch {
|
|
|
- padding: 20px 10px;
|
|
|
-}
|
|
|
-.disable{
|
|
|
- color: #f0f0f0 !important;
|
|
|
-}
|
|
|
-.serchBox {
|
|
|
- width: 200px;
|
|
|
- height: 40px;
|
|
|
- border: 1px solid #eee;
|
|
|
- position: relative;
|
|
|
-}
|
|
|
-.serchBox img {
|
|
|
- position: absolute;
|
|
|
- right: 10px;
|
|
|
- top: 12px;
|
|
|
-}
|
|
|
-.serchBox input {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- background: #f5f5f5;
|
|
|
- border: none;
|
|
|
- color: #999;
|
|
|
- padding: 0 10px;
|
|
|
-}
|
|
|
-.serchBox input:focus {
|
|
|
- outline: none;
|
|
|
- color: #666;
|
|
|
-}
|
|
|
-.FastReplyList {
|
|
|
- width: 100%;
|
|
|
-}
|
|
|
-.userinfo {
|
|
|
- width: 21vw;
|
|
|
- padding: 20px;
|
|
|
- background: #ECF4FF;
|
|
|
-}
|
|
|
-.userData p {
|
|
|
- line-height: 30px;
|
|
|
- display: block;
|
|
|
- width: 100%;
|
|
|
-}
|
|
|
-.message_box{
|
|
|
- background:#F5F5F5;
|
|
|
- border-radius: 10px 0 10px 10px;
|
|
|
-}
|
|
|
-.user_box{
|
|
|
- background:#DFF0FF;
|
|
|
- border-radius: 0 10px 10px 10px;
|
|
|
-}
|
|
|
-
|
|
|
-.userDataInput {
|
|
|
- width: 80%;
|
|
|
- padding: 10px;
|
|
|
- height: 50px;
|
|
|
- resize: none;
|
|
|
- border: 1px solid #d5e5ff;
|
|
|
- background: #fff;
|
|
|
-}
|
|
|
-.userDataInput:focus {
|
|
|
- outline: none;
|
|
|
-}
|
|
|
-.userBtn {
|
|
|
- width: 60px;
|
|
|
- height: 34px;
|
|
|
- border: 1px solid rgba(221, 221, 221, 1);
|
|
|
- background: linear-gradient(
|
|
|
- 180deg,
|
|
|
- rgba(245, 245, 245, 1) 0%,
|
|
|
- rgba(238, 238, 238, 1) 100%
|
|
|
- );
|
|
|
- border-radius: 5px;
|
|
|
- color: #888;
|
|
|
- font-size: 14px;
|
|
|
- margin-top: 10px;
|
|
|
-}
|
|
|
-.chatmin {
|
|
|
- height: 46.5vh;
|
|
|
-}
|
|
|
-
|
|
|
-.el-button--primary{
|
|
|
- background:#409EFF !important;
|
|
|
- /* color:#fff !important; */
|
|
|
- border:1px solid #DCDFE6;
|
|
|
- line-height: 1;
|
|
|
- padding: 4px 8px;
|
|
|
-}
|
|
|
-.cell button{
|
|
|
- line-height: 1;
|
|
|
- -webkit-transition: .1s;
|
|
|
- border-radius: 4px;
|
|
|
- border: 1px solid #DCDFE6;
|
|
|
- padding: 4px 8px;
|
|
|
-}
|
|
|
-.el-button{
|
|
|
- line-height: 0 ;
|
|
|
- /* width: 0; */
|
|
|
- border:none ;
|
|
|
- padding: 0 ;
|
|
|
- color: #999 ;
|
|
|
- font-size: 12px ;
|
|
|
- font-weight:400 ;
|
|
|
-}
|
|
|
+ .el-icon-arrow-right:before {
|
|
|
+ content: "\E791";
|
|
|
+ color: #ccc;
|
|
|
+ }
|
|
|
+ .session_choose{
|
|
|
+ background:#F6F8FF;
|
|
|
+ }
|
|
|
+ .session_style:hover {
|
|
|
+ /* background:#F6F8FF; */
|
|
|
+ background:#ECF4FF ;
|
|
|
+ cursor:pointer;
|
|
|
+ }
|
|
|
+ .sessionList {
|
|
|
+ width: 21vw;
|
|
|
+ background: #fff;
|
|
|
+ }
|
|
|
+ .markNumber{
|
|
|
+ display: inline-block;
|
|
|
+ width:20px;
|
|
|
+ height:20px;
|
|
|
+ border-radius: 50%;
|
|
|
+ background:#f60;
|
|
|
+ font-size:12px;
|
|
|
+ color:#fff;
|
|
|
+ text-align: center;
|
|
|
+ line-height: 20px;
|
|
|
+ }
|
|
|
+ .el-collapse-item__header {
|
|
|
+ position: relative;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight:bold;
|
|
|
+ color:#666;
|
|
|
+ font-family:PingFang SC;
|
|
|
+ padding-left: 32px;
|
|
|
+ height: 49px;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding-right: 10px;
|
|
|
+ }
|
|
|
+ .el-collapse-item__header.is-active {
|
|
|
+ border-bottom: 1px solid #d5e5ff;
|
|
|
+ }
|
|
|
+ .el-collapse-item__header {
|
|
|
+ border-bottom: 1px solid #d5e5ff;
|
|
|
+ }
|
|
|
+ .el-icon-arrow-right {
|
|
|
+ position: absolute;
|
|
|
+ left: 10px;
|
|
|
+ top: auto;
|
|
|
+ }
|
|
|
+ .sessionList_span {
|
|
|
+ color: #999;
|
|
|
+ }
|
|
|
+ .user {
|
|
|
+ padding: 10px;
|
|
|
+ }
|
|
|
+ .evaluation{
|
|
|
+ font-size: 24px;
|
|
|
+ color: #969696;
|
|
|
+ }
|
|
|
+ .el-collapse-item__content {
|
|
|
+ padding-bottom: 0;
|
|
|
+ }
|
|
|
+ .chat {
|
|
|
+ width: 29vw;
|
|
|
+ height: 93vh;
|
|
|
+ border: 1px solid #d5e5ff;
|
|
|
+ border-top: none;
|
|
|
+ background: #fff;
|
|
|
+ }
|
|
|
+ .user_text{
|
|
|
+ border: 1px solid #ECF4FF;
|
|
|
+ color:#999;
|
|
|
+ line-height: 30px;
|
|
|
+ width: 80%;
|
|
|
+ }
|
|
|
+ .user_text:focus {
|
|
|
+ outline: none;
|
|
|
+ }
|
|
|
+ .chatTop {
|
|
|
+ height: 50px;
|
|
|
+ border-bottom: 1px solid #d5e5ff;
|
|
|
+ }
|
|
|
+ .chat-box {
|
|
|
+ height: 62vh;
|
|
|
+ /* background: red; */
|
|
|
+ /* padding: 40px 0; */
|
|
|
+ border-bottom: 1px solid #d5e5ff;
|
|
|
+ overflow-x: hidden;
|
|
|
+ overflow-y: auto;
|
|
|
+ }
|
|
|
+ .chatMsg {
|
|
|
+ display: inline-block;
|
|
|
+ padding: 10px;
|
|
|
+ font-size: 14px;
|
|
|
+ max-width: 85%;
|
|
|
+ word-wrap: break-word;
|
|
|
+ }
|
|
|
+ p {
|
|
|
+ margin-block-start: 0em;
|
|
|
+ margin-block-end: 0em;
|
|
|
+ margin-inline-start: 0px;
|
|
|
+ margin-inline-end: 0px;
|
|
|
+ }
|
|
|
+ .frce {
|
|
|
+ height: 0.38rem;
|
|
|
+ width: 100%;
|
|
|
+ padding: 16px 10px;
|
|
|
+ }
|
|
|
+ .input {
|
|
|
+ height: 100px;
|
|
|
+ background: #fff;
|
|
|
+ resize: none;
|
|
|
+ font-size: 14px;
|
|
|
+ margin: 0 10px;
|
|
|
+ border: none;
|
|
|
+ /* border: 1px solid #d5e5ff; */
|
|
|
+ }
|
|
|
+ .input:focus {
|
|
|
+ outline: none;
|
|
|
+ border: none;
|
|
|
+ }
|
|
|
+ .user_info_box{
|
|
|
+ margin: 10px 0 ;
|
|
|
+ }
|
|
|
+ .title_span{
|
|
|
+ color:#666;
|
|
|
+ font-size:14px;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ .content_span{
|
|
|
+ color:#999;
|
|
|
+ font-size:14px;
|
|
|
+ }
|
|
|
+ .key {
|
|
|
+ /* width: 27.8vw; */
|
|
|
+ /* position: absolute; */
|
|
|
+ bottom: 22px;
|
|
|
+ height: 23vh;
|
|
|
+ /* background: #409EFF; */
|
|
|
+ }
|
|
|
+ .msgInputBtn {
|
|
|
+ right: 10px;
|
|
|
+ bottom: 10px;
|
|
|
+ width: 60px;
|
|
|
+ height: 30px;
|
|
|
+ /* background:#ECF4FF; */
|
|
|
+ background:#5399f5;
|
|
|
+ margin-right: 10px;
|
|
|
+ border-radius: 5px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #fff;
|
|
|
+ cursor:pointer;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* .msgInputBtn:hover{
|
|
|
+ background:#5399f5;
|
|
|
+ } */
|
|
|
+ .frceBox {
|
|
|
+ position: absolute;
|
|
|
+ /* top: 25vw; */
|
|
|
+ bottom: 25vh;
|
|
|
+ left: 31.5vw;
|
|
|
+ width: 28vw;
|
|
|
+ height: 25vh;
|
|
|
+ background: #fff;
|
|
|
+ border: 1px solid #d5e5ff;
|
|
|
+ overflow-x: hidden;
|
|
|
+ overflow-y: auto;
|
|
|
+ z-index: 999999;
|
|
|
+ }
|
|
|
+ .frceBox p {
|
|
|
+ width: 50px;
|
|
|
+ height: 50px;
|
|
|
+ }
|
|
|
+ .FastReply {
|
|
|
+ width: 19vw;
|
|
|
+ height: 92vh;
|
|
|
+ border-right: 1px solid #d5e5ff;
|
|
|
+ background: #fff;
|
|
|
+ }
|
|
|
+ .FastReplyHader {
|
|
|
+ height: 50px;
|
|
|
+ border-bottom: 1px solid #d5e5ff;
|
|
|
+ padding: 0 10px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #666;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ .FastReplySwitch {
|
|
|
+ height: 50px;
|
|
|
+ border-bottom: 1px solid #d5e5ff;
|
|
|
+ color: #666;
|
|
|
+ font-size: 14px;
|
|
|
+ padding: 0 40px;
|
|
|
+ }
|
|
|
+ .FastReplySwitch p.active {
|
|
|
+ position: relative;
|
|
|
+ color:#5399f5;
|
|
|
+ }
|
|
|
+ .FastReplySwitch p.active::after {
|
|
|
+ content: "";
|
|
|
+ display: inline-block;
|
|
|
+ position: absolute;
|
|
|
+ width: 42px;
|
|
|
+ height: 2px;
|
|
|
+ left: 1px;
|
|
|
+ bottom: -15px;
|
|
|
+ background: #5399f5;
|
|
|
+ }
|
|
|
+ ul{
|
|
|
+ margin-block-start: 0.4em;
|
|
|
+ margin-block-end: 0.4em;
|
|
|
+ }
|
|
|
+ .cursor_text{
|
|
|
+ cursor:pointer;
|
|
|
+ margin: 10px 20px;
|
|
|
+ }
|
|
|
+ .cursor_text:hover{
|
|
|
+ color: #d5e5ff;
|
|
|
+ background: #f6f8ff;
|
|
|
+ }
|
|
|
+ .serch {
|
|
|
+ padding: 20px 10px;
|
|
|
+ }
|
|
|
+ .disable{
|
|
|
+ color: #f0f0f0 !important;
|
|
|
+ }
|
|
|
+ .serchBox {
|
|
|
+ width: 200px;
|
|
|
+ height: 40px;
|
|
|
+ border: 1px solid #eee;
|
|
|
+ position: relative;
|
|
|
+ }
|
|
|
+ .serchBox img {
|
|
|
+ position: absolute;
|
|
|
+ right: 10px;
|
|
|
+ top: 12px;
|
|
|
+ }
|
|
|
+ .serchBox input {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ background: #f5f5f5;
|
|
|
+ border: none;
|
|
|
+ color: #999;
|
|
|
+ padding: 0 10px;
|
|
|
+ }
|
|
|
+ .serchBox input:focus {
|
|
|
+ outline: none;
|
|
|
+ color: #666;
|
|
|
+ }
|
|
|
+ .FastReplyList {
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ .userinfo {
|
|
|
+ width: 21vw;
|
|
|
+ padding: 20px;
|
|
|
+ background: #ECF4FF;
|
|
|
+ }
|
|
|
+ .userData p {
|
|
|
+ line-height: 30px;
|
|
|
+ display: block;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ .message_box{
|
|
|
+ background:#F5F5F5;
|
|
|
+ border-radius: 10px 0 10px 10px;
|
|
|
+ }
|
|
|
+ .user_box{
|
|
|
+ background:#DFF0FF;
|
|
|
+ border-radius: 0 10px 10px 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .userDataInput {
|
|
|
+ width: 80%;
|
|
|
+ padding: 10px;
|
|
|
+ height: 50px;
|
|
|
+ resize: none;
|
|
|
+ border: 1px solid #d5e5ff;
|
|
|
+ background: #fff;
|
|
|
+ }
|
|
|
+ .userDataInput:focus {
|
|
|
+ outline: none;
|
|
|
+ }
|
|
|
+ .userBtn {
|
|
|
+ width: 60px;
|
|
|
+ height: 34px;
|
|
|
+ border: 1px solid rgba(221, 221, 221, 1);
|
|
|
+ background: linear-gradient(
|
|
|
+ 180deg,
|
|
|
+ rgba(245, 245, 245, 1) 0%,
|
|
|
+ rgba(238, 238, 238, 1) 100%
|
|
|
+ );
|
|
|
+ border-radius: 5px;
|
|
|
+ color: #888;
|
|
|
+ font-size: 14px;
|
|
|
+ margin-top: 10px;
|
|
|
+ }
|
|
|
+ .chatmin {
|
|
|
+ height: 46.5vh;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-button--primary{
|
|
|
+ background:#409EFF !important;
|
|
|
+ /* color:#fff !important; */
|
|
|
+ border:1px solid #DCDFE6;
|
|
|
+ line-height: 1;
|
|
|
+ padding: 4px 8px;
|
|
|
+ }
|
|
|
+ .cell button{
|
|
|
+ line-height: 1;
|
|
|
+ -webkit-transition: .1s;
|
|
|
+ border-radius: 4px;
|
|
|
+ border: 1px solid #DCDFE6;
|
|
|
+ padding: 4px 8px;
|
|
|
+ }
|
|
|
+ .el-button{
|
|
|
+ line-height: 0 ;
|
|
|
+ /* width: 0; */
|
|
|
+ border:none ;
|
|
|
+ padding: 0 ;
|
|
|
+ color: #999 ;
|
|
|
+ font-size: 12px ;
|
|
|
+ font-weight:400 ;
|
|
|
+ }
|
|
|
</style>
|