856 行
40 KiB
JavaScript
856 行
40 KiB
JavaScript
define(['vue'], function (Vue) {
|
|
Vue.directive('dialogDrag', {
|
|
bind(el, binding, vnode, oldVnode) {
|
|
const dialogHeaderEl = el.querySelector('.el-dialog__header');
|
|
const dragDom = el.querySelector('.el-dialog');
|
|
|
|
dialogHeaderEl.style.cssText += ';cursor:move;'
|
|
dragDom.style.cssText += ';top:0px;'
|
|
|
|
const sty = (() => {
|
|
if (window.document.currentStyle) {
|
|
return (dom, attr) => dom.currentStyle[attr];
|
|
} else {
|
|
return (dom, attr) => getComputedStyle(dom, false)[attr];
|
|
}
|
|
})()
|
|
dialogHeaderEl.onmousedown = (e) => {
|
|
document.onselectstart = function () {
|
|
return false;
|
|
};
|
|
document.ondragstart = function () {
|
|
return false;
|
|
};
|
|
$(document).find("iframe").css("pointer-events", "none");
|
|
const disX = e.clientX - dialogHeaderEl.offsetLeft;
|
|
const disY = e.clientY - dialogHeaderEl.offsetTop;
|
|
|
|
const screenWidth = document.body.clientWidth;
|
|
const screenHeight = document.documentElement.clientHeight;
|
|
|
|
const dragDomWidth = dragDom.offsetWidth;
|
|
const dragDomheight = dragDom.offsetHeight;
|
|
const minDragDomLeft = dragDom.offsetLeft;
|
|
const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth;
|
|
|
|
const minDragDomTop = dragDom.offsetTop;
|
|
const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight;
|
|
let styL = sty(dragDom, 'left');
|
|
let styT = sty(dragDom, 'top');
|
|
if (styL.includes('%')) {
|
|
styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100);
|
|
styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100);
|
|
} else {
|
|
styL = +styL.replace(/\px/g, '');
|
|
styT = +styT.replace(/\px/g, '');
|
|
};
|
|
document.onmousemove = function (e) {
|
|
let left = e.clientX - disX;
|
|
let top = e.clientY - disY;
|
|
if (-(left) > minDragDomLeft) {
|
|
left = -(minDragDomLeft);
|
|
} else if (left > maxDragDomLeft) {
|
|
left = maxDragDomLeft;
|
|
}
|
|
if (-(top) > minDragDomTop) {
|
|
top = -(minDragDomTop);
|
|
} else if (top > maxDragDomTop) {
|
|
top = maxDragDomTop;
|
|
}
|
|
|
|
dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`;
|
|
};
|
|
document.onmouseup = function (e) {
|
|
document.onselectstart = function () {
|
|
return true;
|
|
};
|
|
$(document).find("iframe").css("pointer-events", "auto");
|
|
document.onmousemove = null;
|
|
document.onmouseup = null;
|
|
};
|
|
}
|
|
}
|
|
})
|
|
Vue.component('Chat', {
|
|
template: '#chatTemp',
|
|
props: ['passvalue'],
|
|
data() {
|
|
return {
|
|
isButtonShow: false,
|
|
isClick: false,
|
|
dialogVisible: false,
|
|
lineOptions: [{
|
|
value: 'online',
|
|
label: '在线',
|
|
color: '#7438D5',
|
|
}, {
|
|
value: 'offline',
|
|
label: '离开',
|
|
color: '#ED655F',
|
|
}, {
|
|
value: 'busy',
|
|
label: '忙碌',
|
|
color: '#666666',
|
|
}],
|
|
lineStatus: '',
|
|
liaoData: [{
|
|
title: '会话中',
|
|
type: 'buyerOnlines',
|
|
|
|
}, {
|
|
title: '排队中',
|
|
type: 'buyerWaitings',
|
|
}, {
|
|
title: '历史记录',
|
|
type: 'buyerHistories',
|
|
}],
|
|
openGroupList: [],
|
|
groupIndex: 0,
|
|
|
|
commonWordsvisible: false,
|
|
sendMessage: '',
|
|
|
|
specificChatMessage: [],
|
|
last_id: '',
|
|
page: 1,
|
|
per_page: 10,
|
|
|
|
emoji_list: [],
|
|
emojivisible: false,
|
|
|
|
websocket: null,
|
|
relink: 0,
|
|
max_relink: 0,
|
|
buylist: {
|
|
buyerHistories: [],
|
|
buyerOnlines: [],
|
|
buyerWaitings: [],
|
|
},
|
|
|
|
isChatingId: '',
|
|
|
|
temporaryObj: {}, //临时消息的id
|
|
user_offline: [], //用户下线
|
|
shoproKefuShake: false,
|
|
shoproChatContainerRefScrollTop: 0,
|
|
scrollHeight: 0,
|
|
|
|
message_num: 10,
|
|
adminData: [],
|
|
commonWordsList: [],
|
|
timeInterval: null,
|
|
kefuButtonvisible: false,
|
|
rightShowId: null,
|
|
rightShowPosition: {
|
|
top: 0,
|
|
left: 0
|
|
},
|
|
changeKefu: null,
|
|
|
|
changeKefuList: [],
|
|
value: '',
|
|
transferAdminList: '',
|
|
openPing: null,
|
|
errorTipVisible: false,
|
|
|
|
// 客服是否介入
|
|
kefuAccessStatus: false,
|
|
kefuAccessStatusSend: false,
|
|
kefuAccessTip: '',
|
|
kefuLinkNum: 0
|
|
|
|
}
|
|
},
|
|
created() {
|
|
this.adminData = this.passvalue.adminData;
|
|
this.emoji_list = this.passvalue.emoji_list;
|
|
this.commonWordsList = this.passvalue.commonWordsList;
|
|
if ("WebSocket" in window) {
|
|
this.linkWebSocket(this.passvalue.wsUri, this.passvalue.token, this.passvalue.expire_time, this.passvalue.customer_service_id);
|
|
} else {
|
|
this.$notify({
|
|
title: '警告',
|
|
message: `浏览器不支持 WebSocket!`,
|
|
type: 'warning'
|
|
});
|
|
}
|
|
},
|
|
mounted() {
|
|
this.$nextTick(() => {
|
|
if (localStorage.getItem("shopro_kefu_button_position")) {
|
|
let left = localStorage.getItem("shopro_kefu_button_position").split(',')[0];
|
|
let top = localStorage.getItem("shopro_kefu_button_position").split(',')[1];
|
|
this.$refs.shoproKefuButtonRef.style.left = `${left}px`;
|
|
this.$refs.shoproKefuButtonRef.style.top = `${top}px`
|
|
this.isButtonShow = true;
|
|
} else {
|
|
this.isButtonShow = true;
|
|
}
|
|
window.onresize = () => {
|
|
return (() => {
|
|
// this.dialogVisible = false;
|
|
this.$refs.shoproKefuButtonRef.style.left = `unset`;
|
|
this.$refs.shoproKefuButtonRef.style.top = `80%`;
|
|
this.rightShowId = null;
|
|
})();
|
|
};
|
|
})
|
|
},
|
|
methods: {
|
|
closerightShowId() {
|
|
this.rightShowId = null;
|
|
this.$forceUpdate();
|
|
},
|
|
show(e, service_id) {
|
|
if (this.groupIndex == 0) {
|
|
this.rightShowId = service_id;
|
|
this.rightShowPosition.top = e.clientY + 'px';
|
|
this.rightShowPosition.left = e.clientX + 'px';
|
|
}
|
|
},
|
|
transferKfu(value) {
|
|
let data = {
|
|
session_id: this.rightShowId,
|
|
identify: 'customer_service',
|
|
type: 'transfer',
|
|
data: {
|
|
customer_service_id: value
|
|
}
|
|
}
|
|
this.websocket.send(JSON.stringify(data));
|
|
this.rightShowId = null;
|
|
this.isChatingId = false
|
|
},
|
|
getimageload(index) {
|
|
this.$set(this.specificChatMessage[index], 'hidden', true)
|
|
},
|
|
imagerror(index) {
|
|
this.$set(this.specificChatMessage[index], 'hidden', true)
|
|
},
|
|
linkWebSocket(wsUri, token, expire_time, customer_service_id) {
|
|
this.errorTipVisible = false
|
|
wsUri = wsUri + '?identify=customer_service&token=' + token + '&expire_time=' + expire_time + '&customer_service_id=' + customer_service_id
|
|
this.websocket = new WebSocket(wsUri);
|
|
this.websocket.onopen = (evt) => {
|
|
this.relink = 1;
|
|
this.openPing = setInterval(() => {
|
|
let data = {
|
|
type: 'ping',
|
|
}
|
|
this.websocket.send(JSON.stringify(data));
|
|
}, 20000)
|
|
};
|
|
this.websocket.onclose = (evt) => {
|
|
this.errorTipVisible = true
|
|
this.lineStatus = 'offline'
|
|
this.kefuLinkNum++
|
|
if(this.kefuLinkNum<=3){
|
|
this.linkWebSocket(this.passvalue.wsUri, this.passvalue.token, this.passvalue.expire_time, this.passvalue.customer_service_id);
|
|
}
|
|
};
|
|
this.websocket.onmessage = (evt) => {
|
|
let result = JSON.parse(evt.data);
|
|
let data = result.data;
|
|
if (result.code) {
|
|
switch (result.type) {
|
|
case 'nologin': //请先登录管理后台
|
|
this.$notify({
|
|
title: '警告',
|
|
message: '请先登录管理后台',
|
|
type: 'warning'
|
|
});
|
|
break;
|
|
case 'no_customer_service': //您还不是客服
|
|
this.$notify({
|
|
title: '警告',
|
|
message: '您还不是客服',
|
|
type: 'warning'
|
|
});
|
|
break;
|
|
case 'init': //链接成功
|
|
this.lineStatus = data.customer_service.status;
|
|
this.buylist.buyerHistories = data.histories;
|
|
this.buylist.buyerOnlines = data.onlines;
|
|
this.buylist.buyerWaitings = data.waitings;
|
|
this.openGroupList = this.buylist[this.liaoData[this.groupIndex].type];
|
|
this.buylist.buyerHistories.forEach(h => {
|
|
if (h.status == 0) {
|
|
this.user_offline.push(h.session_id)
|
|
}
|
|
})
|
|
this.lineStatus = 'online'
|
|
break;
|
|
case 'customer_service_update':
|
|
if (data.customer_services.length > 0) {
|
|
data.customer_services.forEach((i, index) => {
|
|
if (i.id == this.adminData.customer_service.id) {
|
|
data.customer_services.splice(index, 1)
|
|
}
|
|
})
|
|
}
|
|
this.changeKefuList = data.customer_services;
|
|
break;
|
|
case 'transfer_success':
|
|
this.transferAdminList = ''
|
|
this.buylist.buyerOnlines.forEach((i, index) => {
|
|
if (i.session_id == data.session_id) {
|
|
this.buylist.buyerOnlines.splice(index, 1)
|
|
}
|
|
})
|
|
break;
|
|
case 'user_online': //用户上线
|
|
if (this.user_offline.includes(data.session_id)) {
|
|
this.user_offline.splice(this.user_offline.indexOf(data.session_id), 1)
|
|
}
|
|
// 更改历史接待人状态上线
|
|
this.buylist.buyerHistories.forEach(history => {
|
|
if (history.session_id == data.session_id) {
|
|
history.customer_service = data.customer_service
|
|
history.status = 1
|
|
}
|
|
})
|
|
break;
|
|
case 'user_offline': //用户下线
|
|
this.user_offline.push(data.session_id);
|
|
// 更改历史接待人状态下线
|
|
this.buylist.buyerHistories.forEach(history => {
|
|
if (history.session_id == data.session_id) {
|
|
history.customer_service = null
|
|
history.status = 0
|
|
}
|
|
})
|
|
break;
|
|
case 'user_accessed': //用户被接入 从排队中删除
|
|
if (this.buylist.buyerWaitings.length > 0) {
|
|
this.buylist.buyerWaitings.forEach((i, index) => {
|
|
if (i.session_id == data.session_id) {
|
|
this.buylist.buyerWaitings.splice(index, 1)
|
|
}
|
|
})
|
|
}
|
|
//切换列表
|
|
// this.changeGroup(0)
|
|
// 更改历史接待人状态上线
|
|
this.buylist.buyerHistories.forEach(history => {
|
|
if (history.session_id == data.session_id) {
|
|
history.customer_service = data.customer_service
|
|
history.status = 1
|
|
}
|
|
})
|
|
// 前台刷新
|
|
if (this.adminData.customer_service.id != data.customer_service.id) {
|
|
let deleteIndex = -1
|
|
this.buylist.buyerOnlines.forEach((online, oindex) => {
|
|
if (online.session_id == data.session_id) {
|
|
deleteIndex = oindex
|
|
}
|
|
})
|
|
if (deleteIndex != -1) {
|
|
this.buylist.buyerOnlines.splice(deleteIndex, 1)
|
|
}
|
|
}
|
|
break;
|
|
case 'user_access': //用户接入 从排队中删除,放到会话中
|
|
this.voicePlay();
|
|
this.rightShowId = null;
|
|
if (this.buylist.buyerWaitings.length > 0) {
|
|
this.buylist.buyerWaitings.forEach((i, index) => {
|
|
if (i.session_id == data.session_id) {
|
|
this.buylist.buyerWaitings.splice(index, 1)
|
|
}
|
|
})
|
|
}
|
|
let flag = true
|
|
if (this.buylist.buyerOnlines.length > 0) {
|
|
this.buylist.buyerOnlines.forEach(i => {
|
|
if (i.session_id == data.session_id) {
|
|
flag = false
|
|
}
|
|
})
|
|
}
|
|
if (flag) {
|
|
this.buylist.buyerOnlines.push(data.chat_user)
|
|
}
|
|
break;
|
|
case 'receipt': //发送成功
|
|
this.$refs.shoproChatContainerRef.scrollTop = this.$refs.shoproChatContainerRef.scrollHeight;
|
|
$(".shopro-send-pre").empty();
|
|
break;
|
|
case 'message': //接收到消息
|
|
this.voicePlay();
|
|
this.rightShowId = null;
|
|
this.kefuButtonvisible = true;
|
|
if (data.message.message_type == 'text') {
|
|
data.message.message = this.replaceEmjio(data.message.message);
|
|
}
|
|
if (data.message.message_type == 'goods' || data.message.message_type == 'order') {
|
|
data.message.message = JSON.parse(data.message.message);
|
|
}
|
|
if (this.isChatingId == data.session_id) {
|
|
this.specificChatMessage.push(data.message)
|
|
} else {
|
|
this.buylist.buyerOnlines.forEach(k => {
|
|
if (k.session_id == data.session_id) {
|
|
k.message_unread_num++
|
|
}
|
|
})
|
|
}
|
|
let addIndex = true
|
|
this.buylist.buyerOnlines.forEach((j, jindex) => {
|
|
if (j.session_id == data.session_id) {
|
|
j.last_message = data.message
|
|
addIndex = false
|
|
}
|
|
})
|
|
if (addIndex) {
|
|
this.buylist.buyerOnlines.unshift({
|
|
avatar: data.message.identify.avatar,
|
|
createtime: data.message.identify.createtime,
|
|
customer_service_id: data.message.identify.customer_service_id,
|
|
id: data.message.identify.id,
|
|
last_message: data.message,
|
|
lasttime: data.message.identify.lasttime,
|
|
message_unread_num: 1,
|
|
nickname: data.message.identify.nickname,
|
|
session_id: data.message.identify.session_id,
|
|
status: 1,
|
|
updatetime: data.message.identify.updatetime,
|
|
user_id: data.message.identify.user_id,
|
|
})
|
|
}
|
|
this.$forceUpdate();
|
|
//调整滚动条
|
|
this.$nextTick(() => {
|
|
if (this.$refs.shoproChatContainerRef) {
|
|
this.$refs.shoproChatContainerRef.scrollTop = this.$refs.shoproChatContainerRef.scrollHeight;
|
|
}
|
|
})
|
|
this.shoproKefuShake = true
|
|
break;
|
|
case 'message_list': //接收到的消息列表
|
|
data.message_list.data.forEach(i => {
|
|
if (i.message_type == 'goods' || i.message_type == 'order') {
|
|
i.message = JSON.parse(i.message)
|
|
}
|
|
if (i.message_type == 'text') {
|
|
i.message = this.replaceEmjio(i.message);
|
|
}
|
|
});
|
|
//拿到this.last_id
|
|
if (this.page == 1 && data.message_list.data.length > 0) {
|
|
this.last_id = data.message_list.data[0].id
|
|
}
|
|
this.message_num = JSON.parse(JSON.stringify(data.message_list.data)).length
|
|
|
|
this.specificChatMessage = data.message_list.data.reverse().concat(this.specificChatMessage)
|
|
//滚动条
|
|
this.$nextTick(() => {
|
|
if (this.page == 1) {
|
|
this.$refs.shoproChatContainerRef.scrollTop = this.$refs.shoproChatContainerRef.scrollHeight;
|
|
} else {
|
|
this.$refs.shoproChatContainerRef.scrollTop = this.$refs.shoproChatContainerRef.scrollHeight - this.scrollHeight;
|
|
}
|
|
|
|
//保存原来的滚动条
|
|
this.scrollHeight = this.$refs.shoproChatContainerRef.scrollHeight;
|
|
|
|
this.$refs.shoproChatContainerRef.removeEventListener("scroll", this.listmore, false);
|
|
this.$refs.shoproChatContainerRef.addEventListener('scroll', this.listmore, false)
|
|
})
|
|
this.shoproKefuShake = false;
|
|
|
|
break;
|
|
case 'del_success': //接收到的消息列表
|
|
this.buylist[this.liaoData[this.groupIndex].type].forEach((i, index) => {
|
|
if (i.session_id == data.session_id) {
|
|
this.buylist[this.liaoData[this.groupIndex].type].splice(index, 1)
|
|
}
|
|
})
|
|
this.isChatingId = null;
|
|
break;
|
|
case 'switch_ok':
|
|
this.lineStatus = data.status
|
|
break;
|
|
}
|
|
|
|
} else {
|
|
this.$notify({
|
|
title: '警告',
|
|
message: `错误响应:${result.msg}`,
|
|
type: 'warning'
|
|
});
|
|
}
|
|
};
|
|
this.websocket.onerror = (evt) => { };
|
|
},
|
|
closeErrorTipVisible() {
|
|
this.errorTipVisible = false
|
|
},
|
|
listmore() {
|
|
let that = this;
|
|
if (that.$refs.shoproChatContainerRef.scrollTop <= 0 && that.message_num == 10) {
|
|
this.page++;
|
|
let ChatingData = {
|
|
identify: 'customer_service',
|
|
type: 'message_list',
|
|
session_id: that.isChatingId,
|
|
data: {
|
|
page: that.page,
|
|
per_page: that.per_page,
|
|
last_id: that.last_id
|
|
}
|
|
}
|
|
that.websocket.send(JSON.stringify(ChatingData));
|
|
}
|
|
},
|
|
//切换在线状态
|
|
changeLineStatus(value) {
|
|
this.lineStatus = value;
|
|
let lineStatusData = {
|
|
identify: 'customer_service',
|
|
type: 'switch_status',
|
|
data: {
|
|
status: value
|
|
}
|
|
}
|
|
this.websocket.send(JSON.stringify(lineStatusData));
|
|
},
|
|
//更换左侧列表
|
|
changeGroup(index) {
|
|
this.kefuAccessStatus = false;
|
|
this.kefuAccessStatusSend = false;
|
|
this.kefuAccessTip = ''
|
|
this.isChatingId = '';
|
|
this.groupIndex = index;
|
|
this.openGroupList = this.buylist[this.liaoData[this.groupIndex].type];
|
|
},
|
|
//选择聊天
|
|
selectChating(chatid, index, opt, row) {
|
|
this.rightShowId = null;
|
|
this.kefuAccessStatus = false;
|
|
this.kefuAccessStatusSend = false;
|
|
this.kefuAccessTip = ''
|
|
|
|
//避免重复请求
|
|
if (chatid == this.isChatingId && opt) {
|
|
return false;
|
|
}
|
|
|
|
this.isChatingId = chatid;
|
|
this.page = 1;
|
|
this.specificChatMessage = [];
|
|
this.message_num = 10;
|
|
this.scrollHeight = 0;
|
|
|
|
//清除未读
|
|
this.buylist[this.liaoData[this.groupIndex].type][index].message_unread_num = 0;
|
|
//将排队中的拿过来
|
|
if (this.groupIndex == 1) {
|
|
this.buylist.buyerWaitings.splice(index, 1);
|
|
let data = {
|
|
session_id: chatid,
|
|
identify: 'customer_service',
|
|
type: 'access',
|
|
}
|
|
this.websocket.send(JSON.stringify(data)); //
|
|
} else {
|
|
let ChatingData = {
|
|
identify: 'customer_service',
|
|
type: 'message_list',
|
|
session_id: this.isChatingId,
|
|
data: {
|
|
page: this.page,
|
|
per_page: this.per_page,
|
|
// last_id: 第一页不用传,以后一直传 第一页的第一条的消息的 id
|
|
}
|
|
}
|
|
this.websocket.send(JSON.stringify(ChatingData));
|
|
|
|
// 监听这个dom的scroll事件
|
|
if (this.$refs.shoproChatContainerRef) {
|
|
this.$refs.shoproChatContainerRef.removeEventListener("scroll", this.listmore, false);
|
|
}
|
|
}
|
|
if (this.groupIndex == 2) {
|
|
if (row.status == 1) {
|
|
if (!row.customer_service) {
|
|
this.kefuAccessStatus = true;
|
|
this.kefuAccessStatusSend = true;
|
|
this.kefuAccessTip = '等待客服接入';
|
|
return false
|
|
}
|
|
if (row.customer_service && row.customer_service.id != this.adminData.customer_service.id) {
|
|
this.kefuAccessStatus = true;
|
|
this.kefuAccessStatusSend = true;
|
|
this.kefuAccessTip = '客服 ' + row.customer_service.name + ' 正在服务,暂时无法与之会话!';
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
},
|
|
closeKefuAccessStatus() {
|
|
this.kefuAccessStatus = false;
|
|
this.kefuAccessTip = ''
|
|
},
|
|
deleteChating(chatid, index, opt) {
|
|
let data = {
|
|
identify: 'customer_service',
|
|
type: 'del_user',
|
|
data: {
|
|
session_id: chatid
|
|
}
|
|
}
|
|
this.websocket.send(JSON.stringify(data));
|
|
},
|
|
selectCommonWords(index) {
|
|
this.commonWordsvisible = false;
|
|
this.doSend('text', this.commonWordsList[index].content)
|
|
this.specificChatMessage.push(this.initSendData('text', this.commonWordsList[index].content));
|
|
},
|
|
selectEmoji(emoji) {
|
|
this.emojivisible = false
|
|
$(".shopro-send-pre").append(`<img class="emoji" src="${'/assets/addons/shopro/img/emoji/' + emoji.file}"/>`)
|
|
},
|
|
selectGoods() {
|
|
let that = this;
|
|
parent.Fast.api.open("shopro/goods/goods/select?multiple=false", "选择商品", {
|
|
callback: function (data) {
|
|
that.doSend('goods', {
|
|
id: data.data.id,
|
|
title: data.data.title,
|
|
image: data.data.image,
|
|
price: data.data.price,
|
|
stock: data.data.stock
|
|
})
|
|
that.specificChatMessage.push(that.initSendData('goods', data.data));
|
|
}
|
|
});
|
|
},
|
|
openGoods(id) {
|
|
Fast.api.open("shopro/goods/goods/edit/ids/" + id + "?id=" + id + "&type=edit", '查看商品');
|
|
},
|
|
openOrder(id) {
|
|
Fast.api.open('shopro/order/order/detail?id=' + id, '查看订单');
|
|
},
|
|
successMessage(event) {
|
|
if (this.lineStatus == 'offline') {
|
|
this.$notify({
|
|
title: '警告',
|
|
message: '离开不能发消息,请切换为在线',
|
|
type: 'warning'
|
|
});
|
|
return false
|
|
}
|
|
if (event) {
|
|
//enter
|
|
if (event.keyCode == "13" && !event.ctrlKey) {
|
|
event.preventDefault();
|
|
event.cancelBubble = true;
|
|
let html = $(".shopro-send-pre").html();
|
|
var reg = new RegExp('<div><br></div>', "g")
|
|
html = html.replace(reg, '')
|
|
if (html) {
|
|
this.doSend('text', html)
|
|
this.specificChatMessage.push(this.initSendData('text', html));
|
|
} else {
|
|
this.$notify({
|
|
title: '警告',
|
|
message: '消息不能为空',
|
|
type: 'warning'
|
|
});
|
|
$(".shopro-send-pre").html('')
|
|
return false;
|
|
}
|
|
} else if (event.keyCode == "13" && event.ctrlKey) {
|
|
$('.shopro-send-pre').html($('.shopro-send-pre').html() + "<div><br/></div>");
|
|
var send = $('.shopro-send-pre')[0];
|
|
//兼容问题
|
|
if (window.getSelection) {
|
|
send.focus();
|
|
var move = window.getSelection();
|
|
move.selectAllChildren(send);
|
|
move.collapseToEnd();
|
|
} else if (document.selection) {
|
|
var move = document.selection.createRange();
|
|
move.moveToElementText(send);
|
|
move.collapse(false);
|
|
move.select();
|
|
}
|
|
}
|
|
} else {
|
|
//发送按钮
|
|
if ($(".shopro-send-pre").html()) {
|
|
this.doSend('text', $(".shopro-send-pre").html())
|
|
this.specificChatMessage.push(this.initSendData('text', $(".shopro-send-pre").html()));
|
|
} else {
|
|
this.$notify({
|
|
title: '警告',
|
|
message: '消息不能为空',
|
|
type: 'warning'
|
|
});
|
|
return false;
|
|
}
|
|
}
|
|
},
|
|
handleClose() {
|
|
this.dialogVisible = false;
|
|
this.shoproKefuShake = false;
|
|
this.kefuButtonvisible = false;
|
|
this.rightShowId = null;
|
|
},
|
|
moveKefu(e) {
|
|
this.isClick = false
|
|
let odiv = e.target;
|
|
document.onselectstart = function () {
|
|
return false;
|
|
};
|
|
document.ondragstart = function () {
|
|
return false;
|
|
};
|
|
$(document).find("iframe").css("pointer-events", "none");
|
|
let disX = e.clientX - odiv.offsetLeft;
|
|
let disY = e.clientY - odiv.offsetTop;
|
|
document.onmousemove = (e) => {
|
|
let left = e.clientX - disX;
|
|
let top = e.clientY - disY;
|
|
if (Math.abs(left - this.positionY + top - this.positionX) > 6) {
|
|
this.isClick = true;
|
|
}
|
|
this.positionX = top;
|
|
this.positionY = left;
|
|
|
|
odiv.style.left = left + 'px';
|
|
odiv.style.top = top + 'px';
|
|
|
|
var shopro_kefu_button_position = [left, top];
|
|
localStorage.setItem("shopro_kefu_button_position", shopro_kefu_button_position);
|
|
document.querySelector(".error-tip-popover").style.left = (left - 275) + 'px'
|
|
document.querySelector(".error-tip-popover").style.top = (top + 3) + 'px';
|
|
};
|
|
document.onmouseup = (e) => {
|
|
document.onselectstart = function () {
|
|
return true;
|
|
};
|
|
document.onmousemove = null;
|
|
document.onmouseup = null;
|
|
$(document).find("iframe").css("pointer-events", "auto");
|
|
};
|
|
},
|
|
openDialog() {
|
|
if (!this.isClick) {
|
|
this.dialogVisible = true;
|
|
this.kefuButtonvisible = false;
|
|
}
|
|
},
|
|
addfile(event) {
|
|
let that = this;
|
|
let formData = new FormData();
|
|
formData.append("file", that.$refs.inputFileRef.files[0]);
|
|
$.ajax({
|
|
url: window.location.origin + "/addons/shopro/index/upload",
|
|
type: 'post',
|
|
data: formData,
|
|
contentType: false,
|
|
processData: false,
|
|
success: function (res) {
|
|
that.doSend('image', res.data.url)
|
|
that.specificChatMessage.push(that.initSendData('image', res.data.url))
|
|
},
|
|
error: function (e) {
|
|
layer.msg('文件上传失败');
|
|
},
|
|
complete: function () {
|
|
that.$refs.inputFileRef.value = ""
|
|
}
|
|
})
|
|
},
|
|
voicePlay() {
|
|
new Audio('/assets/addons/shopro/audio/notice.wav').play();
|
|
},
|
|
//发送消息的数据组装
|
|
doSend(type, message, index) {
|
|
var submessage = message
|
|
if (type == 'text') {
|
|
let reg = /<img class="emoji".*?(?:>|\/>)/gi; // [] img
|
|
let zhEmojiName = submessage.match(reg);
|
|
if (zhEmojiName) {
|
|
zhEmojiName.forEach(item => {
|
|
let srcReg = /src=[\'\"]?([^\'\"]*)[\'\"]?/i
|
|
let path = item.match(srcReg)[1]
|
|
let pathArr = path.split('/');
|
|
let file = pathArr[pathArr.length - 1];
|
|
let noimage = {
|
|
name: '[常用语]'
|
|
}
|
|
let emojiItem = this.selEmjioFile('file', file) ? this.selEmjioFile('file', file) : noimage;
|
|
submessage = submessage.replace(
|
|
item, `${emojiItem.name}`
|
|
);
|
|
});
|
|
}
|
|
}
|
|
let data = {
|
|
session_id: this.isChatingId,
|
|
identify: 'customer_service',
|
|
type: 'message',
|
|
message: {
|
|
message_type: type,
|
|
message: submessage
|
|
},
|
|
}
|
|
this.websocket.send(JSON.stringify(data));
|
|
},
|
|
|
|
//发送之前处理数据
|
|
initSendData(type, message) {
|
|
return {
|
|
message: message,
|
|
message_type: type,
|
|
sender_identify: "customer_service",
|
|
identify: this.adminData.customer_service
|
|
}
|
|
},
|
|
timeFilter(datetime) {
|
|
let timeday = ''
|
|
// let timestamp = Date.parse(new Date())
|
|
let datestamp = new Date(datetime)
|
|
// if (timestamp - datetime < 86400) {
|
|
// var hour = ("0" + datestamp.getHours()).slice(-2),
|
|
// minute = ("0" + datestamp.getMinutes()).slice(-2);
|
|
// timeday = hour + ":" + minute
|
|
// }else if (timestamp - datetime < 172800 && timestamp - datetime > 86400) {
|
|
// timeday = '昨天'
|
|
// } else {
|
|
timeday = datestamp.getFullYear() + '/' + (Number(datestamp.getMonth()) + 1) + '/' + datestamp.getDate() + ' ' + ("0" + datestamp.getHours()).slice(-2) + ':' + ("0" + datestamp.getMinutes()).slice(-2)
|
|
// }
|
|
return timeday;
|
|
},
|
|
|
|
// 表情地址
|
|
selEmjioFile(type, value) {
|
|
for (let index in this.emoji_list) {
|
|
if (this.emoji_list[index][type] === value) {
|
|
return this.emoji_list[index];
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
// 替换表情
|
|
replaceEmjio(data) {
|
|
let newData = data;
|
|
let reg = /\[(.+?)\]/g; // [] 中括号
|
|
let zhEmojiName = newData.match(reg);
|
|
if (zhEmojiName) {
|
|
zhEmojiName.forEach(item => {
|
|
let emojiItem = this.selEmjioFile('name', item);
|
|
newData = newData.replace(
|
|
item,
|
|
`<img class="emoji" src="${'/assets/addons/shopro/img/emoji/' + emojiItem.file}"/>`
|
|
);
|
|
});
|
|
}
|
|
return newData;
|
|
},
|
|
},
|
|
})
|
|
}) |