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.
go-fly/static/html/chat_page.html

495 lines
20 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<html lang="cn">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="陶士涵">
<title>GO-FLY咨询页</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/element-ui@2.13.1/lib/theme-chalk/index.css">
<script src="/static/js/functions.js?v=0.1.1"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/element-ui@2.13.1/lib/index.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js"></script>
<!-- Bootstrap core CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel="stylesheet" href="/static/css/common.css?v=0.1.1" />
<style>
html,
body {
height: 100%;
background: #fff;
}
.chatCenter{background: #fff;max-width: 800px;margin: 0 auto;}
.chatContext{
padding:0 10px;
width: 100%;
text-align: left;
position: relative;
margin-bottom: 86px;
}
.chatBox{
/*max-height: 600px;*/
/*overflow-y: auto;*/
/*overflow-x: hidden;*/
/*margin-bottom: 80px;*/
}
.chatBox .el-col{margin:10px 0;}
.chatUser{
line-height: 24px;
font-size: 12px;
white-space: nowrap;
color: #999;
text-align: left;
}
.chatContent{
background-color: rgb(166,212,242);
color: #000;
border: 1px solid rgb(152, 199, 230);
padding: 8px 15px;
min-height: 35px;
word-break: break-all;
position: relative;
border-radius: 5px;
display: inline-block;
margin-left: 6px;
}
.chatContent:after {
content: '';
position: absolute;
left: -10px;
top: 13px;
width: 0;
height: 0;
border-style: dashed;
border-color: transparent;
overflow: hidden;
border-width: 10px;
border-top-style: solid;
border-top-color: rgb(166,212,242);
}
.chatBoxMe .chatContent{float: right;background-color: rgb(152,225,101);border: 1px solid rgb(145, 215, 96);}
.chatBoxMe .chatContent:after{border-top-color: rgb(152,225,101);}
.chatBoxMe .el-col-3{float: right;text-align: right;}
.chatBoxMe .chatUser{text-align: right}
.chatBoxMe .chatContent:after{left:auto;right: -10px;}
.chatArea{float: left;width: 85%;margin: 4px 0 0 4px;}
.btnArea{width: 10%;float: right;}
@media screen and (max-width: 500px) {
body{background: #fff}
.chatArea {width: 70%;}
.btnArea{width: 20%;}
}
.chatTitle{height: 30px;line-height: 30px;color: #1989fa}
.chatBoxSend{background: #f5f5f5;position: fixed;bottom: 0;width: 100%;height: 86px;max-width: 800px;}
.chatBoxSendBtn{float: right;margin: 12px 4px 0 0;}
.chatTime{text-align: center;color: #bbb;margin: 5px 0;font-size: 12px;}
.chatTimeHide{display: none;}
.clear{clear:both;}
</style>
</head>
<body>
<div id="app" class="chatCenter">
<template>
<!--客服代码-->
<div class="chatContext">
<div class="chatBox">
<el-alert
style="margin-bottom: 10px;font-size: 12px;"
title="公告 : 访客您好欢迎star fork github https://github.com/taoshihan1991/go-fly ,感谢您的支持。"
type="success">
</el-alert>
<el-alert
style="margin-bottom: 10px;"
:title="chatTitle"
:closable="false"
type="success">
</el-alert>
<el-row :gutter="2" v-for="v in msgList" v-bind:class="{'chatBoxMe': v.is_kefu==true}">
<div class="chatTime" v-bind:class="{'chatTimeHide': v.show_time==false}"><{v.time}></div>
<el-col :span="3"><el-avatar :src="v.avator"></el-avatar></el-col>
<el-col :span="21">
<div class="chatUser"><{v.name}></div>
<div class="chatContent" v-html="v.content"></div>
</el-col>
<div class="clear"></div>
</el-row>
</div>
</div>
<div class="chatBoxSend">
<div class="iconBtns">
<div class="faceBtn visitorFaceBtn"></div>
<div class="imageBtn visitorImageBtn" id="uploadImg" v-on:click="uploadImg('/uploadimg')"></div>
<div class="clear"></div>
</div>
<el-input type="textarea" class="chatArea" v-model="messageContent" v-on:keyup.enter.native="chatToUser"></el-input>
<div class="faceBox visitorFaceBox">
<ul class="faceBoxList">
<li v-on:click="faceIconClick(i)" class="faceIcon" v-for="(v,i) in face" :title="v.name"><img :src=v.path></li>
</ul>
<div class="clear"></div>
</div>
<div class="btnArea">
<el-button type="primary" class="chatBoxSendBtn" size="small" v-on:click="chatToUser">{{.SendBtn}}</el-button>
</div>
<div class="clear"></div>
</div>
<!--//客服代码-->
</template>
</div>
</body>
<script src="//pv.sohu.com/cityjson?ie=utf-8"></script>
<script src="https://cdn.bootcss.com/reconnecting-websocket/1.0.0/reconnecting-websocket.min.js"></script>
<script>
var KEFU_ID="{{.KEFU_ID}}";
var guest={};
guest.id = "";
guest.name = typeof(returnCitySN)!="undefined" ?returnCitySN["cname"]+"网友":"小米";
guest.avator = "/static/images/"+Math.floor(Math.random()*(14-0+1)+0)+".jpg";
guest.group = "1";
guest.to_id=KEFU_ID!=""? KEFU_ID:"kefu2";
new Vue({
el: '#app',
delimiters:["<{","}>"],
data: {
window:window,
server:getWsBaseUrl()+"/chat_server",
socket:null,
msgList:[],
messageContent:"",
chatTitle:"正在连接...",
visitor:{},
face:[],
},
methods: {
//初始化websocket
initConn() {
let socket = new ReconnectingWebSocket(this.server);//创建Socket实例
this.socket = socket
this.socket.onmessage = this.OnMessage;
this.socket.onopen = this.OnOpen;
this.socket.onclose = this.OnClose;
},
OnOpen() {
this.chatTitle="连接成功! 等待客服接入"
//从缓存中取出用户
let userinfo=this.getUserInfo();
let mes = {}
mes.type = "userInit";
userinfo.client_ip=returnCitySN["cip"];
userinfo.city=returnCitySN["cname"];
userinfo.refer="{{.Refer}}";
mes.data = userinfo;
this.socket.send(JSON.stringify(mes));
},
OnMessage(e) {
const redata = JSON.parse(e.data);
if (redata.type == "kfOnline") {
let msg = redata.data
guest.to_id=msg.id;
this.chatTitle=msg.name+",正在与您沟通!"
$(".chatBox").append("<div class=\"chatTime\">"+this.chatTitle+"</div>");
this.scrollBottom();
}
if (redata.type == "message") {
let msg = redata.data
guest.to_id=msg.id;
let content = {}
content.avator = msg.avator;
content.name = msg.name;
content.content =replaceContent(msg.content);
content.is_kefu = false;
content.time = msg.time;
this.msgList.push(content);
this.saveHistory(content);
this.scrollBottom();
flashTitle();//标题闪烁
}
window.parent.postMessage(redata);
},
//发送给客户
chatToUser() {
if(guest.to_id==""){
this.$message({
message: '暂时没有客服接手',
type: 'warning'
});
return;
}
this.messageContent=this.messageContent.trim("\r\n");
if(this.messageContent==""||this.messageContent=="\r\n"){
this.$message({
message: '不能发送空白信息',
type: 'warning'
});
return;
}
let _this=this;
let mes = {};
mes.type = "visitor";
mes.content = this.messageContent;
mes.from_id = guest.id;
mes.to_id = guest.to_id;
mes.content = this.messageContent;
$.post("/message",mes,function(){
_this.messageContent = "";
});
let content = {}
content.avator=guest.avator;
content.content = replaceContent(this.messageContent);
content.name = guest.name;
content.is_kefu = true;
content.time = this.getNowDate();
this.msgList.push(content);
this.saveHistory(content);
this.scrollBottom();
},
OnClose() {
this.chatTitle="连接关闭!"
},
//获取当前用户信息
getUserInfo(){
let obj=this.getCache("guest");
if(!obj){
guest.id=this.generateUUID();
this.setCache("guest",guest);
obj=this.getCache("guest");
}
guest=obj;
this.visitor=obj;
return obj;
},
//加载历史
getHistory:function(){
let history=this.getCache("history");
if(history==null){
history=[];
}
$.each(history,function(i,val){
history[i]["show_time"]=false;
let lastKey=(i+1)>=history.length?i:i+1;
let lastTime=new Date(history[lastKey]["time"]).getTime();
let curTime=new Date(val["time"]).getTime();
let diffTime=lastTime-curTime
if(diffTime>(1000*60*5)){
history[i]["show_time"]=true;
}
});
console.log(history);
return history;
},
//保存历史
saveHistory:function(row){
let history=this.getHistory("history");
history.push(row);
this.setCache("history",history);
},
//获取信息列表
getMesssagesByVisitorId(){
let _this=this;
$.ajax({
type:"get",
url:"/messages?visitorId="+this.visitor.id,
success: function(data) {
if(data.code==200 && data.result!=null){
let msgList=data.result;
_this.msgList=[];
for(let i=0;i<msgList.length;i++){
let visitorMes=msgList[i];
let content = {}
if(visitorMes["mes_type"]=="kefu"){
content.is_kefu = false;
content.avator = visitorMes["kefu_avator"];
content.name = visitorMes["kefu_name"];
}else{
content.is_kefu = true;
content.avator = visitorMes["visitor_avator"];
content.name = visitorMes["visitor_name"];
}
content.content = replaceContent(visitorMes["content"]);
content.time = visitorMes["time"];
_this.msgList.push(content);
_this.scrollBottom();
}
}
if(data.code!=200){
_this.$message({
message: data.msg,
type: 'error'
});
}
}
});
},
//滚动到底部
scrollBottom:function(){
this.$nextTick(() => {
//debugger;
$('body').scrollTop($("body")[0].scrollHeight);
});
},
//获取日期
getNowDate : function() {// 获取日期
var d = new Date(new Date());
return d.getFullYear() + '-' + this.digit(d.getMonth() + 1) + '-' + this.digit(d.getDate())
+ ' ' + this.digit(d.getHours()) + ':' + this.digit(d.getMinutes()) + ':' + this.digit(d.getSeconds());
},
//补齐数位
digit : function (num) {
return num < 10 ? '0' + (num | 0) : num;
},
setCache : function (key,obj){
if(typeof(Storage) !== "undefined"){
localStorage.setItem(key, JSON.stringify(obj));
}
},getCache : function (key){
return JSON.parse(localStorage.getItem(key));
},
generateUUID:function () {
var d = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (d + Math.random()*16)%16 | 0;
d = Math.floor(d/16);
return (c=='x' ? r : (r&0x3|0x8)).toString(16);
});
return uuid;
},
//获取自动欢迎语句
getNotice : function (){
let _this=this;
$.get("/notice?kefu_id="+guest.to_id+"&lang={{.Lang}}",function(res) {
console.log(res);
if (res.result != null) {
let msg = res.result;
let content = {}
content.avator = msg.avator;
content.name = msg.nickname;
content.content = replaceContent(msg.content);
content.is_kefu = false;
content.time = msg.time;
setTimeout(function () {
_this.msgList.push(content);
_this.scrollBottom();
}, 4000);
;
}
});
},
//获取聊天记录
getHistoryByApi(){
},
initCss(){
var _this=this;
$(function () {
//$(".chatContext").css("max-height",$(window).height());
// if (top.location != location){
// $(".chatContext").css("max-height",$(window).height()-65);
// }
//展示表情
var faces=placeFace();
$.each(faceTitles, function (index, item) {
_this.face.push({"name":item,"path":faces[item]});
});
$(".faceBtn").click(function(){
var status=$('.faceBox').css("display");
if(status=="block"){
$('.faceBox').hide();
}else{
$('.faceBox').show();
}
});
});
},
//心跳
ping(){
let _this=this;
let mes = {}
mes.type = "ping";
mes.data = "";
setInterval(function () {
if(_this.socket!=null){
_this.socket.send(JSON.stringify(mes));
}
},5000);
},
//初始化
init(){
this.initCss();
this.initConn();
window.onfocus = function () {
clearTimeout(titleTimer);
document.title = originTitle;
};
$('body').click(function(){
clearTimeout(titleTimer);
document.title = originTitle;
});
},
//表情点击事件
faceIconClick(index){
$('.faceBox').hide();
this.messageContent+="face"+this.face[index].name;
},
//上传图片
uploadImg (url){
let _this=this;
$('#uploadImg').after('<input type="file" accept="image/gif,image/jpeg,image/jpg,image/png" id="uploadImgFile" name="file" style="display:none" >');
$("#uploadImgFile").click();
$("#uploadImgFile").change(function (e) {
var formData = new FormData();
var file = $("#uploadImgFile")[0].files[0];
formData.append("imgfile",file); //传给后台的file的key值是可以自己定义的
filter(file) && $.ajax({
url: url || '',
type: "post",
data: formData,
contentType: false,
processData: false,
dataType: 'JSON',
mimeType: "multipart/form-data",
success: function (res) {
if(res.code!=200){
_this.$message({
message: res.msg,
type: 'error'
});
}else{
_this.messageContent+='img[/' + res.result.path + ']';
_this.chatToUser();
}
},
error: function (data) {
console.log(data);
}
});
});
},
},
created: function () {
this.init();
this.getUserInfo();
//加载历史记录
this.getMesssagesByVisitorId();
//this.msgList=this.getHistory();
//滚动底部
this.scrollBottom();
//获取欢迎
this.getNotice();
//心跳
this.ping();
}
})
</script>
</html>