You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
zhishifufei_php/application/kefu/view/dashboard/index.php

1031 lines
39 KiB

{extend name="public/container"}
{block name="title"}客服工作台{/block}
{block name="head"}
<style>
@import "/static/css/google.min.css";
.chat-textarea textarea.ivu-input {
border: none;
resize: none;
}
.kefu-layouts {
padding-top: 30px;
height: 100%;
display: flex;
background: #ccc;
overflow: scroll;
}
.content-wrapper {
display: flex;
flex-direction: column;
width: 1200px;
height: 808px;
margin: 0 auto;
background: #fff;
}
.content-wrapper .container {
flex: 1;
display: flex;
}
.content-wrapper .container .chat-content {
width: 600px;
height: 100%;
border-right: 1px solid #ececec;
}
.content-wrapper .container .chat-content .chat-body {
height: 530px;
}
.content-wrapper .container .chat-content .chat-body .chat-item {
margin-bottom: 10px;
}
.content-wrapper .container .chat-content .chat-body .chat-item .time {
text-align: center;
color: #999;
font-size: 14px;
margin: 18px 0;
}
.content-wrapper .container .chat-content .chat-body .chat-item .flex-box {
display: flex;
}
.content-wrapper .container .chat-content .chat-body .chat-item .avatar {
width: 40px;
height: 40px;
margin-right: 16px;
}
.content-wrapper .container .chat-content .chat-body .chat-item .avatar img {
display: block;
width: 100%;
height: 100%;
border-radius: 50%;
}
.content-wrapper .container .chat-content .chat-body .chat-item .msg-wrapper {
max-width: 320px;
background: #f5f5f5;
border-radius: 10px;
color: #000;
font-size: 14px;
overflow: hidden;
}
.content-wrapper .container .chat-content .chat-body .chat-item .msg-wrapper .txt-wrapper {
word-break: break-all;
}
.content-wrapper .container .chat-content .chat-body .chat-item .msg-wrapper .pad16 {
padding: 9px;
}
.content-wrapper .container .chat-content .chat-body .chat-item .msg-wrapper .img-wraper img {
max-width: 100%;
height: auto;
display: block;
}
.content-wrapper .container .chat-content .chat-body .chat-item .msg-wrapper .order-wrapper {
display: flex;
width: 320px;
}
.content-wrapper .container .chat-content .chat-body .chat-item .msg-wrapper .order-wrapper .img-box {
width: 60px;
height: 60px;
}
.content-wrapper .container .chat-content .chat-body .chat-item .msg-wrapper .order-wrapper .img-box img {
width: 100%;
height: 100%;
border-radius: 5px;
}
.content-wrapper .container .chat-content .chat-body .chat-item .msg-wrapper .order-wrapper .order-info {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 224px;
margin-left: 10px;
font-size: 12px;
}
.content-wrapper .container .chat-content .chat-body .chat-item .msg-wrapper .order-wrapper .order-info .price-box {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
color: #f00;
}
.content-wrapper .container .chat-content .chat-body .chat-item .msg-wrapper .order-wrapper .order-info .price-box .more {
font-size: 12px;
color: #1890ff;
}
.content-wrapper .container .chat-content .chat-body .chat-item .msg-wrapper .order-wrapper .order-info .name {
font-size: 14px;
}
.content-wrapper .container .chat-content .chat-body .chat-item .msg-wrapper .order-wrapper .order-info .sku {
margin: 1px 0;
color: #999;
}
.content-wrapper .container .chat-content .chat-body .chat-item.right-box .flex-box {
flex-direction: row-reverse;
}
.content-wrapper .container .chat-content .chat-body .chat-item.right-box .flex-box .avatar {
margin-right: 0;
margin-left: 16px;
}
.content-wrapper .container .chat-content .chat-body .chat-item.right-box .flex-box .msg-wrapper {
background: #cde0ff;
}
.content-wrapper .container .chat-content .chat-body .chat-item.right-box.gary .msg-wrapper {
background: #f5f5f5;
}
.content-wrapper .container .chat-content .chat-textarea {
height: 214px;
border-top: 1px solid #ececec;
}
.content-wrapper .container .chat-content .chat-textarea .chat-btn-wrapper {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
padding: 15px 0;
}
.content-wrapper .container .chat-content .chat-textarea .chat-btn-wrapper .left-wrapper {
display: flex;
align-items: center;
}
.content-wrapper .container .chat-content .chat-textarea .chat-btn-wrapper .left-wrapper .icon-item {
display: flex;
align-items: center;
margin-left: 20px;
cursor: pointer;
}
.content-wrapper .container .chat-content .chat-textarea .chat-btn-wrapper .left-wrapper .icon-item .iconfont {
font-size: 22px;
color: #333;
}
.content-wrapper .container .chat-content .chat-textarea .chat-btn-wrapper .right-wrapper {
position: relative;
padding-right: 20px;
}
.content-wrapper .container .chat-content .chat-textarea .chat-btn-wrapper .right-wrapper .icon-item {
display: flex;
align-items: center;
font-size: 15px;
color: #333;
cursor: pointer;
}
.content-wrapper .container .chat-content .chat-textarea .chat-btn-wrapper .right-wrapper .icon-item span {
margin-left: 10px;
}
.content-wrapper .container .chat-content .chat-textarea .chat-btn-wrapper .right-wrapper .transfer-box {
z-index: 60;
position: absolute;
right: 1px;
bottom: 43px;
width: 140px;
background: #fff;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
padding: 16px;
}
.content-wrapper .container .chat-content .chat-textarea .chat-btn-wrapper .right-wrapper .transfer-bg {
z-index: 50;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: transparent;
}
.content-wrapper .container .chat-content .chat-textarea .chat-btn-wrapper .emoji-box {
position: absolute;
left: 0;
top: 0;
transform: translateY(-100%);
display: flex;
flex-wrap: wrap;
width: 60%;
padding: 15px 9px;
box-shadow: 0px 0px 13px 1px rgba(0, 0, 0, 0.1);
background: #fff;
}
.content-wrapper .container .chat-content .chat-textarea .chat-btn-wrapper .emoji-box .emoji-item {
margin-right: 13px;
margin-bottom: 8px;
cursor: pointer;
}
.content-wrapper .container .chat-content .chat-textarea .chat-btn-wrapper .emoji-box .emoji-item:nth-child(10n) {
margin-right: 0;
}
.send-btn {
position: absolute;
right: 0;
bottom: 10px;
display: flex;
justify-content: flex-end;
margin-top: 10px;
margin-right: 10px;
width: 80px;
}
.send-btn .btns {
width: 100%;
background: #3875ea;
}
.send-btn .btns[disabled] {
background: #ccc;
color: #fff;
}
.bg {
z-index: 100;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
}
.happy-scroll-content {
width: 100%;
}
.happy-scroll-content .demo-spin-icon-load {
animation: ani-demo-spin 1s linear infinite;
}
.happy-scroll-content .demo-spin-col {
height: 100px;
position: relative;
border: 1px solid #eee;
}
@-moz-keyframes ani-demo-spin {
from {
transform: rotate(0deg);
}
50% {
transform: rotate(180deg);
}
to {
transform: rotate(360deg);
}
}
@-webkit-keyframes ani-demo-spin {
from {
transform: rotate(0deg);
}
50% {
transform: rotate(180deg);
}
to {
transform: rotate(360deg);
}
}
@-o-keyframes ani-demo-spin {
from {
transform: rotate(0deg);
}
50% {
transform: rotate(180deg);
}
to {
transform: rotate(360deg);
}
}
@keyframes ani-demo-spin {
from {
transform: rotate(0deg);
}
50% {
transform: rotate(180deg);
}
to {
transform: rotate(360deg);
}
}
.isMsgbox>>>.ivu-modal-body {
padding: 0;
}
.kf_mobile .textarea-box textarea {
resize: none !important;
height: 148px;
border-color: transparent;
font-size: 14px !important;
}
.kf_mobile .textarea-box textarea:focus {
box-shadow: none;
}
</style>
{/block}
{block name="content"}
<div class="kefu-layouts kf_mobile" v-cloak id="app">
<div class="content-wrapper">
<base-header :kefu-info="kefuInfo" :online="online" @set-online="setOnline" @search="bindSearch"></base-header>
<div class="container">
<chat-list @set-data-id="setDataId" @change-type="changeType" :user-online="userOnline" :new-recored="newRecored" :search-data="searchData"></chat-list>
<div class="chat-content">
<div class="chat-body">
<happy-scroll size="5" resize hide-horizontal :scroll-top="scrollTop" @vertical-start="scrollHandler">
<div style="width: 600px; padding: 20px" id="chat_scroll" ref="scrollBox">
<Spin v-show="isLoad">
<Icon type="ios-loading" size="18" class="demo-spin-icon-load"></Icon>
<div>Loading</div>
</Spin>
<div class="chat-item" v-for="(item, index) in records" :key="index" :class="item.classList" :id="`chat_${item.id}`">
<div class="time" v-show="item.show">{{ item.time }}</div>
<div class="time" v-if="item.msn_type == 24 && item.kefu_info">已将用户转接到{{ item.kefu_info.nickname }}</div>
<div class="flex-box" v-else-if="item.msn_type != 24">
<div class="avatar">
<img :src="item.avatar" alt="" />
</div>
<div class="msg-wrapper">
<!-- 文档 -->
<template v-if="item.msn_type <= 2">
<div class="txt-wrapper pad16" v-html="item.msn"></div>
</template>
<!-- 图片 -->
<template v-else-if="item.msn_type == 3">
<div class="img-wraper" v-viewer>
<img :src="item.msn" alt="" />
</div>
</template>
<!-- 商品 -->
<template v-else-if="item.msn_type == 5">
<div class="order-wrapper pad16">
<div class="img-box">
<img :src="item.productInfo?.image" alt="" />
</div>
<div class="order-info">
<div class="name line1">
{{ item.productInfo?.store_name }}
</div>
<div class="sku">{{ getSkuScaleContent(item) }}</div>
<div class="price-box">
<div class="num">
¥ {{ item.productInfo?.price }}
</div>
<a herf="javascript:;" class="more" @click.stop="lookGoods(item)">查看商品 ></a>
</div>
</div>
</div>
</template>
<!-- 订单 -->
<template v-else-if="item.msn_type == 21">
<div class="order-wrapper pad16">
<div class="img-box">
<img :src="
item.orderInfo.cartInfo[0].productInfo.image
" alt="" />
</div>
<div class="order-info">
<div class="name line1">
{{ item.orderInfo.order_id }}
</div>
<div class="sku">
商品数量:{{ item.orderInfo.total_num }}&nbsp;&nbsp;
类型:{{ item.orderInfo.type_name }}
</div>
<div class="price-box">
<div class="num">
¥ {{ item.orderInfo.pay_price }}
</div>
<a href="javascript:;" class="more" @click.stop="lookOrder(item)">查看订单 ></a>
</div>
</div>
</div>
</template>
</div>
</div>
</div>
<div ref="scroll_flag"></div>
</div>
</happy-scroll>
</div>
<div class="chat-textarea">
<div class="chat-btn-wrapper">
<div class="left-wrapper">
<div class="icon-item" @click.stop="isEmoji = !isEmoji">
<span class="iconfont iconbiaoqing1"></span>
</div>
<div class="icon-item">
<Upload :show-upload-list="false" :format="['jpg', 'jpeg', 'png', 'gif']" :on-format-error="handleFormatError" :before-upload="handleUpload">
<span class="iconfont icontupian1"></span>
</Upload>
</div>
<div class="icon-item" @click.stop.stop="isMsg = true">
<span class="iconfont iconliaotian"></span>
</div>
</div>
<div class="right-wrapper">
<div class="icon-item" @click.stop="isTransfer = !isTransfer">
<span class="iconfont iconzhuanjie"></span>
<span>转接</span>
</div>
<div class="transfer-box" v-if="isTransfer">
<transfer @close="msgClose" @transferPeople="transferPeople" :user-uid="userActive.to_uid"></transfer>
</div>
<div class="transfer-bg" v-if="isTransfer" @click.stop="isTransfer = false"></div>
</div>
<!-- 表情 -->
<div class="emoji-box" v-show="isEmoji">
<div class="emoji-item" v-for="(emoji, index) in emojiList" :key="index">
<i class="em" :class="emoji" @click.stop="select(emoji)"></i>
</div>
</div>
</div>
<div class="textarea-box" style="position: relative">
<i-input v-paste="handleParse" v-model="chatCon" type="textarea" :rows="4" @keydown.native="listen($event)" placeholder="请输入文字内容" @on-enter="bindEnter" style="font-size: 14px"></i-input>
<div class="send-btn">
<i-button class="btns" type="primary" :disabled="disabled" @click.stop="sendText">发送</i-button>
</div>
</div>
</div>
</div>
<div>
<right-menu :is-tourist="tourist" :uid="userActive.to_uid" :web-type="userActive.type" @bind-push="bindPush"></right-menu>
</div>
</div>
<!-- 用户标签 -->
<Modal v-model="isMsg" :mask="true" class="none-radius isMsgbox" width="600" :footer-hide="true">
<msg-window v-if="isMsg" @close="msgClose" @active-txt="activeTxt"></msg-window>
</Modal>
<!-- 商品弹窗 -->
<div v-if="isProductBox">
<div class="bg" @click.stop="isProductBox = false"></div>
<goods-detail :goods-info="goodsInfo"></goods-detail>
</div>
<!-- 订单详情 -->
<div v-if="isOrder">
<Modal v-model="isOrder" title="订单信息" width="700" :footer-hide="true" :mask="true" class="none-radius">
<order-detail :order-info="orderInfo"></order-detail>
</Modal>
</div>
</div>
</div>
{/block}
{block name="script"}
<script>
window.$P = JSON.parse.bind(JSON);
const chunk = (arr, num) => {
num = num * 1 || 1;
var ret = [];
arr.forEach(function(item, i) {
if (i % num === 0) {
ret.push([]);
}
ret[ret.length - 1].push(item);
});
return ret;
};
const mp3 = new Audio("/kefu-assets/assets/audio/notice.wav");
require([
"vue",
"iview",
"happy-scroll",
"vue-scroll",
"dayjs",
"v-viewer",
"kefu-assets/api/kefu",
"kefu-assets/libs/socket",
"kefu-assets/libs/emoji",
"kefu-assets/components/pc/base-header/index",
"kefu-assets/components/pc/chat-list/index",
"kefu-assets/components/pc/right-menu/index",
"kefu-assets/components/pc/msg-window/index",
"kefu-assets/components/pc/transfer/index",
"kefu-assets/components/pc/goods-detail/index",
"kefu-assets/components/pc/order-detail/index",
], (Vue, iView, happyScroll, vueScroll, dayjs, VueViewer, kefuApi, Socket, emojiList, baseHeader, chatList, rightMenu, msgWindow, transfer, goodsDetail, orderDetail) => {
Vue.use(happyScroll.default);
Vue.use(vueScroll);
Vue.use(iView);
Vue.use(VueViewer.default);
Vue.prototype.bus = new Vue();
Vue.prototype.$socket = Socket;
const kefuInfo = $P(`{$kefuInfo}`);
new Vue({
el: "#app",
components: {
baseHeader,
chatList,
rightMenu,
msgWindow,
transfer,
goodsDetail,
orderDetail
},
data() {
return {
isEmoji: false,
chatCon: "",
emojiGroup: chunk(emojiList, 20), // 表情列表
emojiList: emojiList,
html: "",
userActive: {}, //左侧用户列表选中信息
kefuInfo, //客服信息
isMsg: false,
isTransfer: false,
activeMsg: "", // 选中的话术
chatList: [],
text: "",
limit: 20,
upperId: 0,
online: true, //当前客服在线状态
scrollTop: 0,
isScroll: true,
oldHeight: 0,
isLoad: false,
isProductBox: false,
goodsInfo: {},
isOrder: false,
orderInfo: {},
upload: "",
userOnline: {},
newRecored: {}, //新对话信息
searchData: "", // 搜索文字
scrollNum: 0, //滚动次数
transferId: "", //转接id
bodyClose: false,
tourist: 0,
};
},
computed: {
disabled() {
if (this.chatCon.length == 0) {
return true;
} else {
return false;
}
},
records() {
return this.chatList.map((item, index) => {
item.time = dayjs(item.add_time * 1000).format("YYYY/MM/DD HH:mm:ss");
if (index) {
if (item.add_time - this.chatList[index - 1].add_time >= 300) {
item.show = true;
} else {
item.show = false;
}
} else {
item.show = true;
}
item.classList = [];
this.kefuInfo.id == item.uid && item.is_kefu_send && item.classList.push('right-box');
item.msn_type == 5 && item.classList.push('gray');
return item;
});
},
},
// 指令粘贴指令定义
directives: {
paste: {
bind(el, binding, vnode) {
el.addEventListener("paste", function(event) {
//这里直接监听元素的粘贴事件
binding.value(event);
});
},
},
},
watch: {
// socketStatus:{
// handler(nVal,Val){
// if(nVal){
// Socket.send({
// data: util.cookies.kefuGet('token'),
// type: "kefu_login"
// });
// }
// },
// deep:true
// }
},
created() {
this.getToken()
.then(token => {
if (!token) return;
this.$socket.then(ws => {
ws.send({
type: "kefu_login",
data: token
});
ws.$on(["reply", "chat"], (data) => {
if (data.is_kefu_send) {
this.online = true;
}
if (!data.is_kefu_send &&
data.uid != this.userActive.to_uid) return;
if (data.msn_type == 1) {
data.msn = this.replace_em(data.msn);
}
if (data.msn_type == 2) {
if (data.msn.indexOf("[") == -1) {
data.msn = this.replace_em(`[${data.msn}]`);
}
}
this.chatList.push(data);
this.$nextTick(() => {
var container = document.querySelector("#chat_scroll");
this.scrollTop = container.offsetHeight;
});
});
ws.$on("socket_error", () => {
this.$Message.error("连接失败");
});
ws.$on("err_tip", (data) => {
this.$Message.error(data.msg);
});
//用户上线提醒广播
ws.$on("user_online", (data) => {
this.userOnline = data;
});
ws.$on("offline", (data) => {
if (!data.self) return;
this.online = false;
});
ws.$on("request_transfer", (data) => {
this.$Modal.confirm({
title: "请求转接用户",
content: data.nickname + "请求将用户转接给您,是否同意?",
cancelText: "拒绝",
onOk: () => {
ws.send({
type: "accept_transfer",
data: {
kefu_id: data.kefu_id,
uid: data.uid
}
});
},
onCancel: () => {
ws.send({
type: "reject_transfer",
data: {
kefu_id: data.kefu_id,
uid: data.uid
}
})
}
});
});
ws.$on("accept_transfer", (data) => {
this.$Notice.success({
title: "同意转接通知",
desc: data.nickname + "已同意您的转接请求"
});
ws.send({
type: "chat",
data: {
msn_type: 24,
msn: data.kefu_id,
to_uid: data.uid,
}
});
});
ws.$on("reject_transfer", (data) => {
this.$Notice.error({
title: "拒绝转接通知",
desc: data.nickname + "已拒绝您的转接请求"
});
});
});
});
},
mounted() {
window.addEventListener("click", function() {
self.isEmoji = false;
});
this.text = this.replace_em("[em-smiling_imp]");
},
methods: {
getSkuScaleContent(item) {
return `库存:${item.productInfo?.stock } 销量:${
parseInt(item.productInfo?.sales) +
parseInt(
item.productInfo?.ficti
? item.productInfo.ficti
: 0
)
}`;
},
async getToken() {
try {
const res = await kefuApi.getToken();
return res.data.token;
} catch (err) {
this.$Message.error(err.msg);
return false;
}
},
handleFormatError(file) {
this.$Message.error("上传图片只能是 jpg、jpg、jpeg、gif 格式!");
},
bindEnter(e) {
if (e.target.value == "") {
return this.$Message.error("请输入消息");
}
this.sendMsg(e.target.value, 1);
this.chatCon = "";
},
//微信截图上传图片时触发
handleParse(e) {
let file = null;
if (
e.clipboardData &&
e.clipboardData.items[0] &&
e.clipboardData.items[0].type &&
e.clipboardData.items[0].type.indexOf("image") > -1
) {
//这里就是判断是否有粘贴进来的文件且文件为图片格式
file = e.clipboardData.items[0].getAsFile();
} else {
this.$Message.warning("上传的文件必须为图片且无法复制本地图片且无法同时复制多张图片");
return;
}
this.update(file);
},
update(e) {
// 上传照片
let file = e;
let param = new FormData(); // 创建form对象
param.append("filename", "file"); // 通过append向form对象添加数据进去
param.append("file", file); // 通过append向form对象添加数据进去
kefuApi.uploadImg(param)
.then(res => {
if (res.code === 200) {
this.$Message.success("上传成功!");
this.sendMsg(res.data.url, 3);
} else {
this.$Message.error(res.msg);
}
})
.catch(err => {
});
},
handleUpload(e) {
this.update(e);
return false;
},
//订单详情
lookOrder(item) {
this.orderInfo = {
...item.orderInfo,
nickname: this.userActive.nickname
};
this.isOrder = true;
},
setOnline(data) {
this.online = data;
this.$socket.then((ws) => {
ws.send({
data: {
online: data,
},
type: "online",
});
});
},
// 阻止浏览器默认换行操作
listen(e) {
if (e.keyCode == 13) {
e.preventDefault();
return false;
}
},
// 输入框选择表情
select(data) {
let val = `[${data}]`;
this.chatCon += val;
this.isEmoji = false;
},
// 聊天表情转换
replace_em(str) {
str = str.replace(/\[em-([a-z_]*)\]/g, "<span class='em em-$1'/></span>");
return str;
},
// 获取是否游客
changeType(data) {
this.tourist = data;
},
// 获取列表用户信息
setDataId(data) {
this.userActive = data;
this.chatList = [];
this.upperId = 0;
this.oldHeight = 0;
this.isScroll = true;
if (data) {
window.document.title = data.nickname ?
`正在和${data.nickname}对话中 - ${this.kefuInfo.site_name}` :
"正在和游客对话中 - " + this.kefuInfo.site_name;
this.getChatList();
kefuApi.setMsgIsRead(data.to_uid);
} else {
window.document.title = this.kefuInfo.site_name;
}
},
msgClose() {
this.isTransfer = false;
},
// 话术选中
activeTxt(data) {
this.chatCon = data;
this.isMsg = false;
},
// 文本发送
sendText() {
this.sendMsg(this.chatCon, 1);
this.chatCon = "";
},
// 统一发送处理
sendMsg(msn, msn_type) {
if (this.userActive && this.userActive.user_id) {
let obj = {
type: "chat",
data: {
msn,
msn_type,
to_uid: this.userActive.to_uid,
is_tourist: this.tourist,
},
};
this.$socket.then((ws) => {
ws.send(obj);
});
}
},
send(type, data) {
Socket.send({
data,
type,
});
},
// 获取聊天列表
getChatList() {
kefuApi.serviceList({
limit: this.limit,
uid: this.userActive.to_uid,
upper_id: this.upperId,
is_tourist: this.tourist,
}).then((res) => {
res.data.forEach((el) => {
if (el.msn_type == 1) {
el.msn = this.replace_em(el.msn);
} else if (el.msn_type == 2) {
el.msn = this.replace_em(`[${el.msn}]`);
}
});
let selector = "";
if (this.upperId == 0) {
selector = "";
} else {
selector = `chat_${this.chatList[0].id}`;
}
// this.chatList = res.data.concat(this.chatList)
this.chatList = [...res.data, ...this.chatList];
this.upperId = res.data.length > 0 ? res.data[0].id : 0;
this.isLoad = false;
this.$nextTick(() => {
// this.scrollToTop()
this.isScroll = res.data.length >= this.limit;
this.setPageScrollTo(selector);
});
});
},
// 设置页面滚动位置
setPageScrollTo(selector) {
this.$nextTick(() => {
if (selector) {
setTimeout(() => {
let num =
parseFloat(document.getElementById(selector).offsetTop) - 60;
this.scrollTop = num;
}, 0);
} else {
var container = document.querySelector("#chat_scroll");
this.scrollTop = container.offsetHeight;
setTimeout((res) => {
if (this.scrollTop != this.$refs.scrollBox.offsetHeight) {
this.scrollTop =
document.querySelector("#chat_scroll").offsetHeight;
}
}, 300);
}
});
},
//滚动到顶部
scrollHandler() {
let self = this;
if (this.isScroll && this.upperId) {
this.isLoad = true;
this.getChatList();
}
},
// 滚动条动画
scrollToTop(duration) {
var container = document.querySelector("#chat_scroll");
this.scrollTop = container.offsetHeight - this.oldHeight;
setTimeout((res) => {
this.scrollTop = this.$refs.scrollBox.offsetHeight - this.oldHeight;
}, 300);
},
// 商品推送
bindPush(data) {
this.sendMsg(data, 5);
},
// 商品详情
lookGoods(item) {
this.goodsInfo = item.productInfo;
this.isProductBox = true;
},
// 搜索用户
bindSearch(data) {
this.searchData = data;
this.oldHeight = 0;
this.upperId = 0;
this.isScroll = false;
},
// 客服转接
transferPeople(data) {
this.transferId = data.id;
this.isTransfer = false;
this.$Message.success("转接成功");
// Socket.then((ws) => {
// ws.send({
// type: "to_chat",
// data: {
// id: data.uid
// },
// });
// });
},
// 客服转接确定
transferOk() {},
},
});
});
</script>
{/block}