kefu/static/templates/default/main.html

551 lines
21 KiB
HTML

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="renderer" content="webkit">
<title>{{.SystemTitle}}</title>
<link rel="stylesheet" href="/static/cdn/element-ui/2.15.1/theme-chalk/index.min.css">
<script src="/static/cdn/vue/2.6.11/vue.min.js"></script>
<script src="/static/cdn/element-ui/2.15.1/index.js"></script>
<script src="/static/cdn/jquery/3.6.0/jquery.min.js"></script>
<link rel="stylesheet" href="/static/css/common.css?v=xxxxxxxxssssss">
<script src="/static/js/reconnecting-websocket.min.js"></script>
<script src="/static/js/functions.js"></script>
<script src="/static/js/chat-lang.js?v=0.7.0"></script>
<script src="/static/js/peer.js"></script>
<script src="/static/js/interact.js"></script>
<link rel="icon" href="/static/images/favicon.ico">
</head>
<body class="text-center" style="overflow-y: hidden;">
<div id="app" style="display: flex">
<template>
{{template "nav" }}
<div class="mainRight">
<iframe title="mainIframe" class="mainIframe" v-bind:src="iframeUrl" frameborder="0" id="mainIframe"></iframe>
</div>
<audio id="chatMessageAudio" src="/static/images/alert.mp3"></audio>
<audio id="visitorAlertAudio" src="/static/images/alert2.ogg"></audio>
<!--视频-->
<div id="remoteVideoBox" class="kefuVideoMask" v-show="isCalling!=''">
<el-button size="mini" class="refuse" @click="callClose()" type="danger">挂断</el-button>
<div class="alignCenter">
<video id="chatRtc" controls autoplay></video>
<video id="chatLocalRtc" controls autoplay muted></video>
</div>
</div>
<!--//视频-->
</template>
</div>
</body>
{{.SystemKefu}}
<script>
var LANG=checkLang();
new Vue({
el: '#app',
delimiters:["<{","}>"],
data: {
window:window,
iframeUrl:"/mainGuide",
mailTotal:0,
adminRole:"",
flyLang:KEFU_LANG[LANG],
host:getBaseUrl(),
kefuId:"",
entId:"",
menuAdminShow:false,
superShow:false,
onlineType:"success",
adminAvator:"",
server:getWsBaseUrl()+"/ws_kefu?token="+localStorage.getItem("token"),
haveNewMessage:"",
countNewMessage:true,
alertSounding:false,
alertSoundingTimer:null,
configs:[],
peerjsId:"",
localStream:null,
isCalling:"",
call:null,
isVideo:false,
},
methods: {
openIframeUrl(url){
this.iframeUrl=url;
this.countNewMessage=true;
},
//退出
logout(){
if(this.onlineType=="success"){
this.upDownLine(2);
}
localStorage.removeItem("token");
this.openIframeUrl('/ironMan/signInx');
},
//跳转
openUrl(url){
window.location.href=url;
},
GetQueryString(name){
var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if(r!=null)return unescape(r[2]); return null;
},
changeOnlineStatus(command){
var _this=this;
sendAjax("/kefu/updateOnlineStatus","get",{status:command},function () {
_this.kefuInfo();
});
},
//初始化websocket
initConn() {
let socket = new ReconnectingWebSocket(this.server);//创建Socket实例
this.socket = socket
this.socket.onmessage = this.OnMessage;
},
OnMessage(e) {
var _this=this;
var redata = JSON.parse(e.data);
var msg = redata.data;
switch (redata.type){
case "unread_num":
redata.data=redata.data==0?"":redata.data;
_this.haveNewMessage=redata.data;
break;
case "notice":
//_this.haveNewMessage="new";
notify(msg.username, {
body: msg.content,
icon: msg.avator
}, function(notification) {
window.focus();
notification.close();
_this.openIframeUrl("/chat_main");
});
if(_this.getConfig("VisitorForceAlert")=="on"){
_this.newVisitorForceAlert(redata.data.username);
}else{
//_this.alertSound();
_this.alertVisitorSound();
}
break;
case "callpeer":
this.handleCall(redata.data);
_this.alertSound();
notify(redata.data.name, {
body: "calling",
icon: "/static/images/video.png"
}, function(notification) {
window.focus();
notification.close();
_this.openIframeUrl("/chat_main");
});
break;
case "callCancel":
this.handleCallCancel(redata.data);
break;
case "message":
if(msg.is_kefu!="no"){
return;
}
if(_this.haveNewMessage==""){
_this.haveNewMessage=0;
}
_this.haveNewMessage++;
notify(msg.name, {
body: msg.content,
icon: msg.avator
}, function(notification) {
window.focus();
notification.close();
_this.openIframeUrl("/chat_main");
});
_this.alertSound();
break;
}
},
kefuInfo(){
let _this=this;
$.ajax({
type:"get",
url:"/kefu/kefuinfo",
headers:{
"token":localStorage.getItem("token")
},
success: function(data) {
if (data.code != 200) {
window.location.href="/ironMan/signInx";
} else {
var result=data.result;
if(result.role_id<=2){
_this.menuAdminShow=true;
}
if(result.role_id==1){
_this.superShow=true;
}
_this.kefuId=result.id;
_this.entId=result.ent_id;
_this.adminAvator=result.avator;
if(result.online_status==1){
_this.onlineType="success";
_this.upDownLine(1);
}else{
_this.onlineType="danger";
}
}
}
});
},
switchLang(command){
setLocalStorage("lang",command);
document.location.reload();
},
//新访客强制提醒
newVisitorForceAlert:function (title) {
var _this=this;
if(_this.alertSounding){
return;
}
var timer=_this.newVisitorForceAlertSound();
this.$confirm(title, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function(){
clearInterval(timer);
_this.alertSounding=false;
}).catch(function(){
clearInterval(timer);
_this.alertSounding=false;
});
_this.alertSounding=true;
},
newVisitorForceAlertSound(){
var _this=this;
var timer=setInterval(function(){
_this.alertSound();
},3000);
_this.alertSoundingTimer=timer;
return timer;
},
getConfigs(){
var _this=this;
sendAjax("/kefu/ent_configs","get",{},function(data){
_this.configs=data.result;
});
},
getConfig(key){
for(index in this.configs){
if(key==this.configs[index].conf_key){
return this.configs[index].conf_value;
}
}
return "";
},
//提示音
alertSound(){
let b = document.getElementById("chatMessageAudio");
let src=this.getConfig("KefuAlertSound");
if(src!=""){
b.src=src;
}
let p = b.play();
p && p.then(function(){}).catch(function(e){});
},
//新访客提示音
alertVisitorSound(){
let b = document.getElementById("visitorAlertAudio");
let src=this.getConfig("visitorLoginSound");
if(src!=""){
b.src=src;
}
let p = b.play();
p && p.then(function(){}).catch(function(e){});
},
//上下线
upDownLine(status){
sendAjax("/kefu/upDownLine?online_status="+status,'get',{},function(){});
},
initPeerjs:function(visitorId){
var _this=this;
var peer = new Peer();
this.peer=peer;
this.peer.on('open', function(id) {
console.log('My peer ID is: ' + id);
_this.peerjsId=id;
sendAjax("/kefu/callVisitor","post",{
peer_id:_this.peerjsId,
visitor_id:visitorId,
"action":"accept"
},function(result){
if(result.code!=200){
_this.$message({
message: _this.flyLang.noVisitors,
type: 'error'
});
}
// _this.$alert(retData.name+'正在通话..', '提示', {
// confirmButtonText: '挂断',
// callback: function(){
// if(_this.mediaConnection!=null){
// _this.mediaConnection.close();
// }
// console.log(_this.mediaConnection);
// }
// });
});
});
this.peer.on('close', function() {
_this.callClear();
console.log('My peer close');
});
this.peer.on('disconnected', function() {
_this.callClear();
console.log('My peer disconnected');
});
this.peer.on('error', function() {
_this.callClear();
console.log('My peer error');
});
this.peer.on('call', function(call) {
_this.call = call;
_this.$confirm(_this.flyLang.videoAudio, _this.flyLang.tips, {
confirmButtonText: _this.flyLang.video,
cancelButtonText: _this.flyLang.recoder,
type: 'warning'
}).then(() => {
_this.isVideo=true;
_this.$confirm("屏幕还是摄像头", _this.flyLang.tips, {
confirmButtonText: _this.flyLang.video,
cancelButtonText: "屏幕",
type: 'warning'
}).then(() => {
_this.startUserMedia(visitorId,false);
}).catch(() => {
_this.startUserMedia(visitorId,true);
});
}).catch(() => {
_this.isVideo=false;
_this.startUserMedia(visitorId,false);
});
});
},
handleCall:function (retData) {
var _this=this;
//正在通话中
if(_this.isCalling!=""){
sendAjax("/kefu/callVisitor","post",{
peer_id:_this.peerjsId,
visitor_id:retData.visitor_id,
"action":"refuse"
},function(res){});
return ;
}
if(_this.alertSounding){
return ;
}
var timer=_this.newVisitorForceAlertSound();
_this.alertSounding=true;
this.$confirm(retData.name+'请求通话?', '提示', {
confirmButtonText: '接通',
cancelButtonText: '取消',
type: 'warning'
}).then(function(){
_this.initPeerjs(retData.visitor_id);
clearInterval(timer);
_this.alertSounding=false;
}).catch(function(){
clearInterval(timer);
_this.alertSounding=false;
sendAjax("/kefu/callVisitor","post",{
peer_id:"222",
visitor_id:retData.visitor_id,
"action":"refuse"
},function(res){});
if(_this.call!=null){
_this.call.close();
}
_this.isCalling="";
_this.$message({
type: 'info',
message: '已拒绝'
});
});
},
handleCallCancel:function (retData) {
var _this=this;
_this.isCalling="";
if(_this.call!=null){
_this.call.close();
}
},
//挂断
callClose(visitorId){
if(!visitorId){
visitorId=this.isCalling;
}
sendAjax("/kefu/callVisitor","post",{
peer_id:"222",
visitor_id:this.isCalling,
"action":"refuse"
},function(res){});
this.callClear();
},
callClear(){
var _this=this;
_this.$message({
type: 'error',
message: "通话已关闭"
});
if(_this.localStream){
var tracks=_this.localStream.getTracks();
for(var i=0;i<tracks.length;i++){
tracks[i].stop();
}
_this.localStream=null;
}
_this.isCalling="";
if(_this.call){
this.call.close();
_this.call=null;
}
},
startUserMedia(visitorId,isScreen){
var _this=this;
_this.isCalling = visitorId;
if(isScreen){
getScreenStream(_this.callbackStream);
return;
}
var getUserMedia = (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia).bind(navigator);;
getUserMedia({video: _this.isVideo, audio: true},_this.callbackStream, function(err) {
console.log('Failed to get local stream' ,err);
sendAjax("/kefu/callVisitor","post",{
peer_id:"222",
visitor_id:visitorId,
"action":"refuse"
},function(res){});
_this.$message({
type: 'error',
message: err
});
});
},
//媒体流回调
callbackStream(stream) {
var _this=this;
_this.localStream = stream;
//本地摄像头
if (_this.isVideo) {
let chatLocalRtc = document.getElementById('chatLocalRtc');
chatLocalRtc.srcObject = _this.localStream;
chatLocalRtc.autoplay = true;
}
_this.$message({
type: 'success',
message: '接通成功!'
});
_this.call.answer(_this.localStream);
_this.call.on('stream', function (remoteStream) {
var remoteVideo = document.querySelector('#chatRtc');
remoteVideo.srcObject = remoteStream;
remoteVideo.autoplay = true;
});
_this.call.on('close', function () {
_this.callClear();
});
_this.call.on('error', function (err) {
_this.$message({
type: 'error',
message: err
});
_this.callClear();
});
},
//心跳
ping(){
var _this=this;
var mes = {};
mes.type = "ping";
setInterval(function () {
if(_this.socket!=null){
_this.socket.send(JSON.stringify(mes));
}
},58000);
},
},
created: function () {
this.kefuInfo();
this.initConn();
this.getConfigs();
var _this=this;
$(function(){
interact('.kefuVideoMask')
.draggable({
onstart: function (event) {
console.log('drag start');
},
onmove: function (event) {
var target = event.target;
var x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
var y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
target.style.transform = 'translate(' + x + 'px, ' + y + 'px)';
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
},
onend: function (event) {
console.log('drag end');
}
});
$("body").on("click",".menuLeftItem",function(){
$(".menuLeftItem").removeClass("active");
$(this).addClass("active");
});
})
//监听iframe传递事件
window.addEventListener('message',function(e){
var msg=e.data;
if(msg.type=="read_num") {
var readNum=msg.data;
if(_this.haveNewMessage) _this.haveNewMessage=_this.haveNewMessage-readNum;
if(_this.haveNewMessage<=0) _this.haveNewMessage="";
}
});
//监听页面关闭
window.onbeforeunload = function(e) {
if(_this.onlineType=="success"){
_this.upDownLine(2);
}
};
this.ping();
}
})
</script>
</html>