From e98db6fe24fae3343eaef8c37d104bc44265c716 Mon Sep 17 00:00:00 2001 From: taoshihan Date: Mon, 21 Jul 2025 23:46:52 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controller/auth.go | 17 - controller/kefu.go | 4 +- controller/login.go | 28 +- controller/main.go | 11 +- controller/message.go | 49 ++ middleware/jwt.go | 10 +- router/api.go | 1 + static/js/chat-main.js | 943 ------------------------------- static/js/chat-page.js | 546 ------------------ static/templates/chat_main.html | 947 +++++++++++++++++++++++++++++++- static/templates/chat_page.html | 550 ++++++++++++++++++- ws/user.go | 25 +- 12 files changed, 1577 insertions(+), 1554 deletions(-) delete mode 100644 controller/auth.go diff --git a/controller/auth.go b/controller/auth.go deleted file mode 100644 index d0874b6..0000000 --- a/controller/auth.go +++ /dev/null @@ -1,17 +0,0 @@ -package controller - -import ( - "github.com/taoshihan1991/imaptool/models" - "github.com/taoshihan1991/imaptool/tools" -) - -func CheckKefuPass(username string, password string) (models.User, models.User_role, bool) { - info := models.FindUser(username) - var uRole models.User_role - if info.Name == "" || info.Password != tools.Md5(password) { - return info, uRole, false - } - uRole = models.FindRoleByUserId(info.ID) - - return info, uRole, true -} diff --git a/controller/kefu.go b/controller/kefu.go index aa9ac9d..21da9a6 100644 --- a/controller/kefu.go +++ b/controller/kefu.go @@ -75,8 +75,8 @@ func PostKefuClient(c *gin.Context) { }) } func GetKefuInfo(c *gin.Context) { - kefuId, _ := c.Get("kefu_id") - user := models.FindUserById(kefuId) + kefuName, _ := c.Get("kefu_name") + user := models.FindUser(kefuName.(string)) info := make(map[string]interface{}) info["name"] = user.Nickname info["id"] = user.Name diff --git a/controller/login.go b/controller/login.go index 3f6534b..ab01a7d 100644 --- a/controller/login.go +++ b/controller/login.go @@ -2,6 +2,7 @@ package controller import ( "github.com/gin-gonic/gin" + "github.com/taoshihan1991/imaptool/models" "github.com/taoshihan1991/imaptool/tools" "log" "net/url" @@ -17,14 +18,12 @@ import ( // @Success 200 {object} controller.Response // @Failure 200 {object} controller.Response // @Router /check [post] -//验证接口 +// 验证接口 func LoginCheckPass(c *gin.Context) { password := c.PostForm("password") username := c.PostForm("username") - - info, uRole, ok := CheckKefuPass(username, password) - userinfo := make(map[string]interface{}) - if !ok { + info := models.FindUser(username) + if info.Name == "" || info.Password != tools.Md5(password) { c.JSON(200, gin.H{ "code": 400, "msg": "验证失败", @@ -32,30 +31,23 @@ func LoginCheckPass(c *gin.Context) { return } - userinfo["name"] = info.Name + userinfo := make(map[string]interface{}) + + userinfo["kefu_name"] = info.Name userinfo["kefu_id"] = info.ID - userinfo["type"] = "kefu" - if uRole.RoleId != 0 { - userinfo["role_id"] = uRole.RoleId - } else { - userinfo["role_id"] = 2 - } userinfo["create_time"] = time.Now().Unix() - token, _ := tools.MakeToken(userinfo) - userinfo["ref_token"] = true - refToken, _ := tools.MakeToken(userinfo) c.JSON(200, gin.H{ "code": 200, "msg": "验证成功,正在跳转", "result": gin.H{ "token": token, - "ref_token": refToken, "create_time": userinfo["create_time"], }, }) } -//远程请求 + +// 远程请求 func PostBindOfficial(c *gin.Context) { api := "https://gofly.v1kf.com/2/officialBindIp" @@ -71,4 +63,4 @@ func PostBindOfficial(c *gin.Context) { log.Println("绑定官网账户发送认证连接错误") } c.Writer.Write([]byte(res)) -} \ No newline at end of file +} diff --git a/controller/main.go b/controller/main.go index a2b306a..3b1e56c 100644 --- a/controller/main.go +++ b/controller/main.go @@ -96,21 +96,20 @@ func install() (bool, error) { return true, nil } func MainCheckAuth(c *gin.Context) { - id, _ := c.Get("kefu_id") - userinfo := models.FindUserRole("user.avator,user.name,user.id, role.name role_name", id) + kefuName, _ := c.Get("kefu_name") + userinfo := models.FindUser(kefuName.(string)) c.JSON(200, gin.H{ "code": 200, "msg": "验证成功", "result": gin.H{ - "avator": userinfo.Avator, - "name": userinfo.Name, - "role_name": userinfo.RoleName, + "avator": userinfo.Avator, + "name": userinfo.Name, }, }) } func GetStatistics(c *gin.Context) { visitors := models.CountVisitors() - message := models.CountMessage(nil,nil) + message := models.CountMessage(nil, nil) session := len(ws.ClientList) kefuNum := 0 c.JSON(200, gin.H{ diff --git a/controller/message.go b/controller/message.go index 5ac9fe2..24b3491 100644 --- a/controller/message.go +++ b/controller/message.go @@ -121,6 +121,55 @@ func SendMessageV2(c *gin.Context) { }) } +} + +func SendKefuMessage(c *gin.Context) { + fromId, _ := c.Get("kefu_name") + toId := c.PostForm("to_id") + content := c.PostForm("content") + cType := c.PostForm("type") + if content == "" { + c.JSON(200, gin.H{ + "code": 400, + "msg": "内容不能为空", + }) + return + } + //限流 + if !tools.LimitFreqSingle("sendmessage:"+c.ClientIP(), 1, 2) { + c.JSON(200, gin.H{ + "code": 400, + "msg": c.ClientIP() + "发送频率过快", + }) + return + } + var kefuInfo models.User + var vistorInfo models.Visitor + kefuInfo = models.FindUser(fromId.(string)) + vistorInfo = models.FindVisitorByVistorId(toId) + + if kefuInfo.ID == 0 || vistorInfo.ID == 0 { + c.JSON(200, gin.H{ + "code": 400, + "msg": "用户不存在", + }) + return + } + + models.CreateMessage(kefuInfo.Name, vistorInfo.VisitorId, content, cType) + //var msg TypeMessage + + guest, ok := ws.ClientList[vistorInfo.VisitorId] + + if guest != nil && ok { + ws.VisitorMessage(vistorInfo.VisitorId, content, kefuInfo) + } + ws.KefuMessage(vistorInfo.VisitorId, content, kefuInfo) + c.JSON(200, gin.H{ + "code": 200, + "msg": "ok", + }) + } func SendVisitorNotice(c *gin.Context) { notice := c.Query("msg") diff --git a/middleware/jwt.go b/middleware/jwt.go index edf7ca7..96a0c73 100644 --- a/middleware/jwt.go +++ b/middleware/jwt.go @@ -21,7 +21,7 @@ func JwtApiMiddleware(c *gin.Context) { token = c.Query("token") } userinfo := tools.ParseToken(token) - if userinfo == nil || userinfo["name"] == nil || userinfo["create_time"] == nil { + if userinfo == nil || userinfo["kefu_name"] == nil || userinfo["create_time"] == nil { c.JSON(200, gin.H{ "code": 400, "msg": "验证失败", @@ -39,11 +39,7 @@ func JwtApiMiddleware(c *gin.Context) { }) c.Abort() } - c.Set("user", userinfo["name"]) - //log.Println(userinfo) - //if userinfo["type"]=="kefu"{ c.Set("kefu_id", userinfo["kefu_id"]) - c.Set("kefu_name", userinfo["name"]) - c.Set("role_id", userinfo["role_id"]) - //} + c.Set("kefu_name", userinfo["kefu_name"]) + } diff --git a/router/api.go b/router/api.go index 1c54bd3..8cf26b9 100644 --- a/router/api.go +++ b/router/api.go @@ -91,6 +91,7 @@ func InitApiRouter(engine *gin.Engine) { kefuGroup.Use(middleware.JwtApiMiddleware) { kefuGroup.GET("/chartStatistics", controller.GetChartStatistic) + kefuGroup.POST("/message", controller.SendKefuMessage) } //微信接口 engine.GET("/micro_program", middleware.JwtApiMiddleware, controller.GetCheckWeixinSign) diff --git a/static/js/chat-main.js b/static/js/chat-main.js index eca2fec..e69de29 100644 --- a/static/js/chat-main.js +++ b/static/js/chat-main.js @@ -1,943 +0,0 @@ -var app=new Vue({ - el: '#app', - delimiters:["<{","}>"], - data: { - visible:false, - chatTitleType:"info", - fullscreenLoading:true, - leftTabActive:"first", - rightTabActive:"visitorInfo", - users:[], - usersMap:[], - server:getWsBaseUrl()+"/ws_kefu?token="+localStorage.getItem("token"), - //server:getWsBaseUrl()+"/chat_server", - socket:null, - socketClosed:false, - messageContent:"", - currentGuest:"", - msgList:[], - chatTitle:"暂时未处理咨询", - chatInputing:"", - kfConfig:{ - id : "kf_1", - name : "客服丽丽", - avator : "", - to_id : "", - }, - visitor:{ - visitor_id:"", - refer:"", - client_ip:"", - city:"", - status:"", - source_ip:"", - created_at:"", - }, - visitorExtra:[], - visitors:[], - visitorCount:0, - visitorCurrentPage:1, - visitorPageSize:10, - face:[], - transKefuDialog:false, - otherKefus:[], - replyGroupDialog:false, - replyContentDialog:false, - editReplyContentDialog:false, - replySearch:"", - replySearchList:[], - replySearchListActive:[], - groupName:"", - groupId:"", - replys:[], - replyId:"", - replyContent:"", - replyTitle:"", - ipBlacks:[], - sendDisabled:false, - showFaceIcon:false, - showLoadMore:false, - messages:{ - page:1, - pagesize:15, - list:[], - }, - }, - methods: { - //跳转 - openUrl(url) { - window.location.href = url; - }, - sendKefuOnline(){ - let mes = {} - mes.type = "kfOnline"; - mes.data = this.kfConfig; - this.socket.send(JSON.stringify(mes)); - }, - //心跳 - ping(){ - let _this=this; - let mes = {} - mes.type = "ping"; - mes.data = ""; - setInterval(function () { - if(_this.socket!=null){ - _this.socket.send(JSON.stringify(mes)); - } - },20000) - setInterval(function(){ - _this.getOnlineVisitors(); - },120000); - }, - //初始化websocket - initConn() { - let socket = new ReconnectingWebSocket(this.server);//创建Socket实例 - this.socket = socket - this.socket.onmessage = this.OnMessage; - this.socket.onopen = this.OnOpen; - }, - OnOpen() { - this.sendKefuOnline(); - }, - OnMessage(e) { - const redata = JSON.parse(e.data); - switch (redata.type){ - case "close": - this.socket.close(); - this.$alert('客服在其他地方登录,当前登录状态退出', '通知', { - confirmButtonText: '确定', - callback:function () { - localStorage.removeItem("token"); - window.location.href="/login"; - } - }); - - break; - case "inputing": - this.handleInputing(redata.data); - //this.sendKefuOnline(); - break; - case "allUsers": - this.handleOnlineUsers(redata.data); - //this.sendKefuOnline(); - break; - case "userOnline": - this.addOnlineUser(redata.data); - - - break; - case "userOffline": - this.removeOfflineUser(redata.data); - //this.sendKefuOnline(); - break; - case "notice": - //发送通知 - var _this=this; - window.parent.postMessage({ - name:redata.data.username, - body: redata.data.content, - icon: redata.data.avator - }); - _this.alertSound(); - break; - } - - - if (redata.type == "message") { - let msg = redata.data - let content = {} - let _this=this; - content.avator = msg.avator; - content.name = msg.name; - content.content = replaceContent(msg.content); - content.is_kefu = msg.is_kefu=="yes"? true:false; - content.time = msg.time; - if (msg.id == this.currentGuest) { - this.msgList.push(content); - } - - for(let i=0;i=_this.messages.pagesize){ - _this.showLoadMore=true; - }else{ - _this.showLoadMore=false; - } - for(let i in msgList){ - let item = msgList[i]; - //let content = {} - if (item["mes_type"] == "kefu") { - item.is_kefu = true; - item.avator=item["kefu_avator"]; - item.name=item["kefu_name"]; - } else { - item.is_kefu = false; - item.avator=item["visitor_avator"]; - item.name=item["visitor_name"]; - } - item.content=replaceContent(item["content"]); - item.time = item["create_time"]; - _this.msgList.unshift(item); - } - if(_this.messages.page==1){ - _this.scrollBottom(); - } - _this.messages.page++; - }); - }, - //获取信息列表 - getMesssagesByVisitorId(visitorId,isAll){ - let _this=this; - $.ajax({ - type:"get", - url:"/messages?visitorId="+visitorId, - headers:{ - "token":localStorage.getItem("token") - }, - success: function(data) { - if(data.code==200 && data.result!=null){ - let msgList=data.result; - _this.msgList=[]; - if(!isAll&&msgList.length>10){ - var i=msgList.length-10 - }else{ - var i=0; - } - for(;i { - $('.chatBox').scrollTop($(".chatBox")[0].scrollHeight); - }); - }, - //jquery - initJquery(){ - this.$nextTick(() => { - var _this=this; - $(function () { - //展示表情 - var faces=placeFace(); - $.each(faceTitles, function (index, item) { - _this.face.push({"name":item,"path":faces[item]}); - }); - - }); - }); - - }, - //表情点击事件 - faceIconClick(index){ - this.showFaceIcon=false; - this.messageContent+="face"+this.face[index].name; - }, - //上传图片 - uploadImg (url){ - let _this=this; - $('#uploadImg').after(''); - $("#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); - } - }); - }); - }, - //上传文件 - uploadFile:function (url){ - let _this=this; - $('#uploadFile').after(''); - $("#uploadRealFile").click(); - $("#uploadRealFile").change(function (e) { - var formData = new FormData(); - var file = $("#uploadRealFile")[0].files[0]; - formData.append("realfile",file); //传给后台的file的key值是可以自己定义的 - console.log(formData); - $.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{ - var data=JSON.stringify({ - name:res.result.name, - ext:res.result.ext, - size:res.result.size, - path:'/' + res.result.path, - }) - _this.messageContent+='attachment['+data+']'; - _this.chatToUser(); - } - }, - error: function (data) { - console.log(data); - } - }); - }); - }, - addIpblack(ip){ - let _this=this; - $.ajax({ - type:"post", - url:"/ipblack", - data:{ip:ip}, - headers:{ - "token":localStorage.getItem("token") - }, - success: function(data) { - if(data.code!=200){ - _this.$message({ - message: data.msg, - type: 'error' - }); - }else{ - _this.$message({ - message: data.msg, - type: 'success' - }); - } - } - }); - }, - //粘贴上传图片 - onPasteUpload(event){ - let items = event.clipboardData && event.clipboardData.items; - let file = null - if (items && items.length) { - // 检索剪切板items - for (var i = 0; i < items.length; i++) { - if (items[i].type.indexOf('image') !== -1) { - file = items[i].getAsFile() - } - } - } - if (!file) { - return; - } - let _this=this; - var formData = new FormData(); - formData.append('imgfile', file); - $.ajax({ - url: '/uploadimg', - 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); - } - }); - }, - openUrl(url){ - window.open(url); - }, - //提示音 - alertSound(){ - var b = document.getElementById("chatMessageAudio"); - var p = b.play(); - p && p.then(function(){}).catch(function(e){}); - }, - sendSound(){ - var b = document.getElementById("chatMessageSendAudio"); - var p = b.play(); - p && p.then(function(){}).catch(function(e){}); - }, - //转移客服 - transKefu(){ - this.transKefuDialog=true; - var _this=this; - this.sendAjax("/other_kefulist","get",{},function(result){ - _this.otherKefus=result; - }); - }, - //转移访客客服 - transKefuVisitor(kefu,visitorId){ - var _this=this; - this.sendAjax("/trans_kefu","get",{kefu_id:kefu,visitor_id:visitorId},function(result){ - //_this.otherKefus=result; - _this.transKefuDialog = false - }); - }, - //保存回复分组 - addReplyGroup(){ - var _this=this; - this.sendAjax("/reply","post",{group_name:_this.groupName},function(result){ - //_this.otherKefus=result; - _this.replyGroupDialog = false - _this.groupName=""; - _this.getReplys(); - }); - }, - //添加回复内容 - addReplyContent(){ - var _this=this; - this.sendAjax("/reply_content","post",{group_id:_this.groupId,item_name:_this.replyTitle,content:_this.replyContent},function(result){ - //_this.otherKefus=result; - _this.replyContentDialog = false - _this.replyContent=""; - _this.getReplys(); - }); - }, - //获取快捷回复 - getReplys(){ - var _this=this; - this.sendAjax("/replys","get",{},function(result){ - _this.replys=result; - }); - }, - //删除回复 - deleteReplyGroup(id){ - var _this=this; - this.sendAjax("/reply?id="+id,"delete",{},function(result){ - _this.getReplys(); - }); - }, - //删除回复 - deleteReplyContent(id){ - var _this=this; - this.sendAjax("/reply_content?id="+id,"delete",{},function(result){ - _this.getReplys(); - }); - }, - //编辑回复 - editReplyContent(save,id,title,content){ - var _this=this; - if(save=='yes'){ - var data={ - reply_id:this.replyId, - reply_title:this.replyTitle, - reply_content:this.replyContent - } - this.sendAjax("/reply_content_save","post",data,function(result){ - _this.editReplyContentDialog=false; - _this.getReplys(); - }); - }else{ - this.editReplyContentDialog=true; - this.replyId=id; - this.replyTitle=title; - this.replyContent=content; - } - - }, - //搜索回复 - searchReply(){ - var _this=this; - _this.replySearchListActive=[]; - if(this.replySearch==""){ - _this.replySearchList=[]; - } - this.sendAjax("/reply_search","post",{search:this.replySearch},function(result){ - _this.replySearchList=result; - for (var i in result) { - _this.replySearchListActive.push(result[i].group_id); - } - }); - }, - //获取黑名单 - getIpblacks(){ - var _this=this; - this.sendAjax("/ipblacks","get",{},function(result){ - _this.ipBlacks=result; - }); - }, - //删除黑名单 - delIpblack(ip){ - let _this=this; - this.sendAjax("/ipblack?ip="+ip,"DELETE",{ip:ip},function(result){ - _this.sendAjax("/ipblacks","get",{},function(result){ - _this.ipBlacks=result; - }); - }); - }, - //划词搜索 - selectText(){ - return false; - var _this=this; - $('body').click(function(){ - try{ - var selecter = window.getSelection().toString(); - if (selecter != null && selecter.trim() != ""){ - _this.replySearch=selecter.trim(); - _this.searchReply(); - }else{ - _this.replySearch=""; - } - } catch (err){ - var selecter = document.selection.createRange(); - var s = selecter.text; - if (s != null && s.trim() != ""){ - _this.replySearch=s.trim(); - _this.searchReply(); - }else{ - _this.replySearch=""; - } - } - var status=$('.faceBox').css("display"); - if(status=="block"){ - $('.faceBox').hide(); - } - }); - }, - sendAjax(url,method,params,callback){ - let _this=this; - $.ajax({ - type: method, - url: url, - data:params, - headers: { - "token": localStorage.getItem("token") - }, - error:function(res){ - var data=JSON.parse(res.responseText); - console.log(data); - if(data.code!=200){ - _this.$message({ - message: data.msg, - type: 'error' - }); - } - }, - success: function(data) { - if(data.code!=200){ - _this.$message({ - message: data.msg, - type: 'error' - }); - }else if(data.result!=null){ - callback(data.result); - }else{ - callback(data); - } - } - }); - }, - }, - mounted() { - document.addEventListener('paste', this.onPasteUpload) - }, - created: function () { - //jquery - this.initJquery(); - this.getKefuInfo(); - this.getOnlineVisitors(); - this.getReplys(); - this.getIpblacks(); - this.selectText(); - //心跳 - this.ping(); - } -}) diff --git a/static/js/chat-page.js b/static/js/chat-page.js index a4d488e..e69de29 100644 --- a/static/js/chat-page.js +++ b/static/js/chat-page.js @@ -1,546 +0,0 @@ -KEFU_ID=KEFU_ID!=""? KEFU_ID:"kefu2"; -new Vue({ - el: '#app', - delimiters:["<{","}>"], - data: { - window:window, - server:getWsBaseUrl()+"/ws_visitor", - socket:null, - msgList:[], - msgListNum:[], - messageContent:"", - chatTitle:GOFLY_LANG[LANG]['connecting'], - visitor:{}, - face:[], - showKfonline:false, - socketClosed:false, - focusSendConn:false, - timer:null, - sendDisabled:false, - flyLang:GOFLY_LANG[LANG], - showIconBtns:false, - showFaceIcon:false, - isIframe:false, - kefuInfo:{}, - showLoadMore:false, - messages:{ - page:1, - pagesize:5, - list:[], - }, - }, - methods: { - //初始化websocket - initConn:function() { - let socket = new ReconnectingWebSocket(this.server+"?visitor_id="+this.visitor.visitor_id);//创建Socket实例 - this.socket = socket - this.socket.onmessage = this.OnMessage; - this.socket.onopen = this.OnOpen; - this.socket.onclose = this.OnClose; - //心跳 - this.ping(); - }, - OnOpen:function() { - console.log("ws:onopen"); - //获取欢迎 - this.getNotice(); - this.socketClosed=false; - this.focusSendConn=false; - }, - OnMessage:function(e) { - console.log("ws:onmessage"); - this.socketClosed=false; - this.focusSendConn=false; - const redata = JSON.parse(e.data); - if (redata.type == "kfOnline") { - let msg = redata.data - if(this.showKfonline && this.visitor.to_id==msg.id){ - return; - } - this.visitor.to_id=msg.id; - this.showTitle(msg.name+","+GOFLY_LANG[LANG]['chating']); - this.scrollBottom(); - this.showKfonline=true; - } - if (redata.type == "transfer") { - var kefuId = redata.data - if(!kefuId){ - return; - } - this.visitor.to_id=kefuId; - } - if (redata.type == "notice") { - let msg = redata.data - if(!msg){ - return; - } - this.chatTitle=msg - $(".chatBox").append("
"+this.chatTitle+"
"); - this.scrollBottom(); - } - if (redata.type == "message") { - let msg = redata.data - this.visitor.to_id=msg.id; - - let content = {} - content.avator = msg.avator; - content.name = msg.name; - content.content =replaceContent(msg.content); - content.is_kefu = true; - content.time = msg.time; - this.msgList.push(content); - - notify(msg.name, { - body: msg.content, - icon: msg.avator - },function(notification) { - window.focus(); - notification.close(); - }); - this.scrollBottom(); - flashTitle();//标题闪烁 - clearInterval(this.timer); - this.alertSound();//提示音 - } - if (redata.type == "close") { - this.chatTitle=GOFLY_LANG[LANG]['closemes']; - $(".chatBox").append("
"+this.chatTitle+"
"); - this.scrollBottom(); - this.socket.close(); - //this.socketClosed=true; - this.focusSendConn=true; - } - if (redata.type == "force_close") { - this.chatTitle=GOFLY_LANG[LANG]['forceclosemes']; - $(".chatBox").append("
"+this.chatTitle+"
"); - this.scrollBottom(); - this.socket.close(); - this.socketClosed=true; - } - if (redata.type == "auto_close") { - this.chatTitle=GOFLY_LANG[LANG]['autoclosemes']; - $(".chatBox").append("
"+this.chatTitle+"
"); - this.scrollBottom(); - this.socket.close(); - this.socketClosed=true; - } - window.parent.postMessage(redata,"*"); - }, - //发送给客户 - chatToUser:function() { - var messageContent=this.messageContent.trim("\r\n"); - messageContent=messageContent.replace("\n",""); - messageContent=messageContent.replace("\r\n",""); - if(messageContent==""||messageContent=="\r\n"){ - this.messageContent=""; - return; - } - this.messageContent=messageContent; - if(this.socketClosed){ - this.$message({ - message: '连接关闭!请重新打开页面', - type: 'warning' - }); - return; - } - this.sendDisabled=true; - let _this=this; - - let content = {} - content.avator=_this.visitor.avator; - content.content = replaceContent(_this.messageContent); - content.name = _this.visitor.name; - content.is_kefu = false; - content.time = _this.getNowDate(); - content.show_time=false; - _this.msgList.push(content); - _this.scrollBottom(); - - let mes = {}; - mes.type = "visitor"; - mes.content = this.messageContent; - mes.from_id = this.visitor.visitor_id; - mes.to_id = this.visitor.to_id; - mes.content = this.messageContent; - //发送消息 - $.post("/2/message",mes,function(res){ - _this.sendDisabled=false; - if(res.code!=200){ - _this.msgList.pop(); - _this.$message({ - message: res.msg, - type: 'error' - }); - return; - } - _this.messageContent = ""; - clearInterval(_this.timer); - _this.sendSound(); - }); - - }, - OnClose:function() { - console.log("ws:onclose"); - this.focusSendConn=true; - //this.socketClosed=true; - // this.chatTitle="连接关闭!请重新打开页面"; - // $(".chatBox").append("
"+this.chatTitle+"
"); - // this.scrollBottom(); - }, - //获取当前用户信息 - getUserInfo:function(){ - let obj=this.getCache("visitor"); - var visitor_id="" - var to_id=KEFU_ID; - if(obj){ - visitor_id=obj.visitor_id; - //to_id=obj.to_id; - } - let _this=this; - var extra=getQuery("extra"); - //发送消息 - $.post("/visitor_login",{visitor_id:visitor_id,refer:REFER,to_id:to_id,extra:extra},function(res){ - if(res.code!=200){ - _this.$message({ - message: res.msg, - type: 'error' - }); - _this.sendDisabled=true; - return; - } - _this.visitor=res.result; - _this.getHistoryMessage(); - _this.setCache("visitor",res.result); - //_this.getMesssagesByVisitorId(); - _this.initConn(); - }); - // }else{ - // this.visitor=obj; - // this.initConn(); - // } - }, - //获取信息列表 - getHistoryMessage:function(){ - let params={ - page:this.messages.page, - pagesize: this.messages.pagesize, - visitor_id: this.visitor.visitor_id, - } - let _this=this; - $.get("/2/messagesPages",params,function(res){ - let msgList=res.result.list; - if(msgList.length>=_this.messages.pagesize){ - _this.showLoadMore=true; - }else{ - _this.showLoadMore=false; - } - for(let i in msgList){ - let item = msgList[i]; - let content = {} - if (item["mes_type"] == "kefu") { - item.is_kefu = true; - item.avator=item["kefu_avator"]; - - } else { - item.is_kefu = false; - item.avator=item["visitor_avator"]; - } - item.time = item["create_time"]; - item.content=replaceContent(item["content"]); - _this.msgList.unshift(item); - } - if(_this.messages.page==1){ - _this.scrollBottom(); - } - _this.messages.page++; - }); - }, - //滚动到底部 - scrollBottom:function(){ - var _this=this; - this.$nextTick(function(){ - $('.chatVisitorPage').scrollTop($(".chatVisitorPage")[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(navigator.cookieEnabled&&typeof window.localStorage !== 'undefined'){ - localStorage.setItem(key, JSON.stringify(obj)); - } - },getCache : function (key){ - if(navigator.cookieEnabled&&typeof window.localStorage !== 'undefined') { - return JSON.parse(localStorage.getItem(key)); - } - }, - //获取自动欢迎语句 - getNotice : function (){ - let _this=this; - $.get("/notice?kefu_id="+KEFU_ID,function(res) { - var code=res.code; - if(code!=200) return; - _this.kefuInfo=res.result; - _this.showTitle(_this.kefuInfo.nickname+" 为您服务"); - if(!_this.kefuInfo.welcome) return; - var msg={ - content:replaceContent(_this.kefuInfo.welcome), - avator:_this.kefuInfo.avatar, - name :_this.kefuInfo.nickname, - time:_this.getNowDate(), - is_kefu:true, - } - _this.msgList.push(msg); - _this.scrollBottom(); - _this.alertSound(); - }); - }, - initCss:function(){ - 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]}); - }); - - - var windheight = $(window).height(); - $(window).resize(function(){ - var docheight = $(window).height(); /*唤起键盘时当前窗口高度*/ - //_this.scrollBottom(); - $('body').scrollTop(99999999); - // if(docheight < windheight){ /*当唤起键盘高度小于未唤起键盘高度时执行*/ - // $(".chatBoxSend").css("position","static"); - // }else{ - // $(".chatBoxSend").css("position","fixed"); - // } - }); - }); - }, - //心跳 - ping:function(){ - let _this=this; - let mes = {} - mes.type = "ping"; - mes.data = "visitor:"+_this.visitor.visitor_id; - setInterval(function () { - if(_this.socket!=null){ - _this.socket.send(JSON.stringify(mes)); - } - },10000); - }, - //初始化 - init:function(){ - var _this=this; - this.initCss(); - $('body').click(function(){ - clearFlashTitle(); - window.parent.postMessage({type:"focus"},"*"); - $('.faceBox').hide(); - }); - window.onfocus = function () { - //_this.scrollBottom(); - clearFlashTitle(); - window.parent.postMessage({type:"focus"},"*"); - if(_this.socketClosed){ - return; - } - if(!_this.focusSendConn){ - return; - } - _this.initConn(); - _this.scrollBottom(); - } - - }, - //表情点击事件 - faceIconClick:function(index){ - $('.faceBox').hide(); - this.messageContent+="face"+this.face[index].name; - }, - //上传图片 - uploadImg:function (url){ - let _this=this; - $('#uploadImg').after(''); - $("#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); - } - }); - }); - }, - //上传文件 - uploadFile:function (url){ - let _this=this; - $('#uploadFile').after(''); - $("#uploadRealFile").click(); - $("#uploadRealFile").change(function (e) { - var formData = new FormData(); - var file = $("#uploadRealFile")[0].files[0]; - formData.append("realfile",file); //传给后台的file的key值是可以自己定义的 - console.log(formData); - $.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{ - var data=JSON.stringify({ - name:res.result.name, - ext:res.result.ext, - size:res.result.size, - path:'/' + res.result.path, - }) - _this.messageContent+='attachment['+data+']'; - _this.chatToUser(); - } - }, - error: function (data) { - console.log(data); - } - }); - }); - }, - //粘贴上传图片 - onPasteUpload:function(event){ - let items = event.clipboardData && event.clipboardData.items; - let file = null - if (items && items.length) { - // 检索剪切板items - for (var i = 0; i < items.length; i++) { - if (items[i].type.indexOf('image') !== -1) { - file = items[i].getAsFile() - } - } - } - if (!file) { - return; - } - let _this=this; - var formData = new FormData(); - formData.append('imgfile', file); - $.ajax({ - url: '/uploadimg', - 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); - } - }); - }, - //提示音 - alertSound:function(){ - alertSound("chatMessageAudio",'/static/images/alert2.ogg'); - }, - sendSound:function(){ - alertSound("chatMessageSendAudio",'/static/images/sent.ogg'); - }, - sendAjax:function(url,method,params,callback){ - let _this=this; - $.ajax({ - type: method, - url: url, - data:params, - error:function(res){ - var data=JSON.parse(res.responseText); - console.log(data); - if(data.code!=200){ - _this.$message({ - message: data.msg, - type: 'error' - }); - } - }, - success: function(data) { - if(data.code!=200){ - _this.$message({ - message: data.msg, - type: 'error' - }); - }else if(data.result!=null){ - callback(data.result); - }else{ - callback(data); - } - } - }); - }, - showTitle:function(title){ - $(".chatBox").append("
"+title+"
"); - this.scrollBottom(); - }, - }, - mounted:function() { - document.addEventListener('paste', this.onPasteUpload) - document.addEventListener('scroll',this.textareaBlur) - }, - created: function () { - this.init(); - this.getUserInfo(); - //加载历史记录 - //this.msgList=this.getHistory(); - //滚动底部 - //this.scrollBottom(); - - } -}) diff --git a/static/templates/chat_main.html b/static/templates/chat_main.html index a8c6300..a50279b 100644 --- a/static/templates/chat_main.html +++ b/static/templates/chat_main.html @@ -321,5 +321,950 @@ - + diff --git a/static/templates/chat_page.html b/static/templates/chat_page.html index 68ad0c8..342b789 100644 --- a/static/templates/chat_page.html +++ b/static/templates/chat_page.html @@ -101,5 +101,553 @@ var LANG=checkLang(); - + diff --git a/ws/user.go b/ws/user.go index d8d31b6..50dd8a5 100644 --- a/ws/user.go +++ b/ws/user.go @@ -11,8 +11,8 @@ import ( ) func NewKefuServer(c *gin.Context) { - kefuId, _ := c.Get("kefu_id") - kefuInfo := models.FindUserById(kefuId) + kefuName, _ := c.Get("kefu_name") + kefuInfo := models.FindUser(kefuName.(string)) if kefuInfo.ID == 0 { c.JSON(200, gin.H{ "code": 400, @@ -32,7 +32,6 @@ func NewKefuServer(c *gin.Context) { kefu.Id = kefuInfo.Name kefu.Name = kefuInfo.Nickname kefu.Avator = kefuInfo.Avator - kefu.Role_id = kefuInfo.RoleId kefu.Conn = conn AddKefuToList(&kefu) @@ -69,16 +68,16 @@ func AddKefuToList(kefu *User) { KefuList[kefu.Id] = kefu } -//给指定客服发消息 +// 给指定客服发消息 func OneKefuMessage(toId string, str []byte) { kefu, ok := KefuList[toId] - if ok{ - log.Println("OneKefuMessage lock") - kefu.Mux.Lock() - defer kefu.Mux.Unlock() - log.Println("OneKefuMessage unlock") - error := kefu.Conn.WriteMessage(websocket.TextMessage, str) - tools.Logger().Println("send_kefu_message", error, string(str)) + if ok { + log.Println("OneKefuMessage lock") + kefu.Mux.Lock() + defer kefu.Mux.Unlock() + log.Println("OneKefuMessage unlock") + error := kefu.Conn.WriteMessage(websocket.TextMessage, str) + tools.Logger().Println("send_kefu_message", error, string(str)) } } func KefuMessage(visitorId, content string, kefuInfo models.User) { @@ -98,7 +97,7 @@ func KefuMessage(visitorId, content string, kefuInfo models.User) { OneKefuMessage(kefuInfo.Name, str) } -//给客服客户端发送消息判断客户端是否在线 +// 给客服客户端发送消息判断客户端是否在线 func SendPingToKefuClient() { msg := TypeMessage{ Type: "many pong", @@ -112,7 +111,7 @@ func SendPingToKefuClient() { defer kefu.Mux.Unlock() err := kefu.Conn.WriteMessage(websocket.TextMessage, str) if err != nil { - log.Println("定时发送ping给客服,失败",err.Error()) + log.Println("定时发送ping给客服,失败", err.Error()) delete(KefuList, kefuId) } }