所有的通讯打通了

This commit is contained in:
LittleBoy 2019-09-28 23:29:50 +08:00
parent f04c873f33
commit c8c614c47b
9 changed files with 168 additions and 109 deletions

View File

@ -1,5 +1,5 @@
const APP = { const APP = {
"KEFUUUID":'chat-kefu-admin', "KF_PREFIX":'chat-admin-',
"QINIU":{ "QINIU":{
"accessKey":"your access key", "accessKey":"your access key",
"secretKey":"your secret key" "secretKey":"your secret key"

196
io/io.js
View File

@ -19,13 +19,13 @@ function ioServer(io) {
var __uuids = []; var __uuids = [];
//初始化连接人数 //初始化连接人数
redis.set('online_count',0,null,function (err,ret) { redis.set('online_count', 0, null, function (err, ret) {
if(err){ if (err) {
console.error(err); console.error(err);
} }
}); });
Array.prototype.remove = function(val) { Array.prototype.remove = function (val) {
var index = this.indexOf(val); var index = this.indexOf(val);
if (index > -1) { if (index > -1) {
this.splice(index, 1); this.splice(index, 1);
@ -43,59 +43,63 @@ function ioServer(io) {
console.log(uid + '登录成功'); console.log(uid + '登录成功');
//通知用户上线 //通知用户上线
if(uid != AppConfig.KEFUUUID){ // 通知给管理员 if (!uid.toString().startsWith(AppConfig.KF_PREFIX)) {
redis.get(AppConfig.KEFUUUID,function (err,sid) { let gongHao = msg.gongHao;
if(err){ console.log('gongHao=>',gongHao)
// 给管理员发送通知
redis.get(AppConfig.KF_PREFIX + gongHao, function (err, sid) {
if (err) {
console.error(err); console.error(err);
} }
if(sid){ console.log('sid=>',sid)
redis.get('online_count',function (err,val) { if (sid) {
if(err){ redis.get('online_count', function (err, val) {
if (err) {
console.error(err); console.error(err);
} }
if(!val){ if (!val) {
val = 0; val = 0;
} }
if(typeof val == 'string'){ if (typeof val == 'string') {
val = parseInt(val); val = parseInt(val);
} }
//var ip = socket.request.connection.remoteAddress; //var ip = socket.request.connection.remoteAddress;
//此处获取IP可能会有延迟建议改成自己的IP库 //此处获取IP可能会有延迟建议改成自己的IP库
Common.getIpLocation(msg.ip,function (err,location) { Common.getIpLocation(msg.ip, function (err, location) {
if(err){ if (err) {
location = ''; location = '';
} }
var info = { var info = {
"uid":uid, "uid": uid,
"name":location + ' 客户', "name": location + ' 客户',
"type":'online' "type": 'online'
}; };
console.log(info);
redis.get('user-uuids',function (err,uuids) { redis.get('user-uuids', function (err, uuids) {
if(err){ if (err) {
console.error(err); console.error(err);
} }
if(uuids){ if (uuids) {
uuids =JSON.parse(uuids); uuids = JSON.parse(uuids);
}else{ } else {
uuids = []; uuids = [];
} }
if(__uuids.indexOf(uid) == -1){ if (__uuids.indexOf(uid) == -1) {
__uuids.push(uid); __uuids.push(uid);
var d_user = {"uid":uid,"name":location + ' 客户'}; var d_user = {"uid": uid, "name": location + ' 客户'};
uuids.push(d_user); uuids.push(d_user);
uuids = JSON.stringify(uuids); uuids = JSON.stringify(uuids);
redis.set('user-uuids',uuids,null,function (err,ret) { redis.set('user-uuids', uuids, null, function (err, ret) {
if(err){ if (err) {
console.error(err); console.error(err);
} }
}); });
} }
}); });
io.to(sid).emit('update-users',info); io.to(sid).emit('update-users', info);
}); });
}); });
@ -103,80 +107,81 @@ function ioServer(io) {
}); });
} }
redis.set(uid,socket.id,null,function (err,ret) { //将用户id和socket进行保定
if(err){ redis.set(uid, socket.id, 3600 * 3, function (err, ret) {
if (err) {
console.error(err); console.error(err);
} }
}); });
redis.set(socket.id,uid,null,function (err,ret) { // redis.set(socket.id,uid,null,function (err,ret) {
if(err){ // if(err){
console.error(err); // console.error(err);
} // }
}); // });
}); });
//断开事件 //断开事件
socket.on('disconnect', function() { socket.on('disconnect', function () {
console.log("与服务其断开"); console.log("与服务其断开");
_self.updateOnlieCount(false); _self.updateOnlieCount(false);
redis.get(socket.id,function (err,val) { redis.get(socket.id, function (err, val) {
if(err){ if (err) {
console.error(err); console.error(err);
} }
redis.del(socket.id,function (err,ret) { redis.del(socket.id, function (err, ret) {
if(err){ if (err) {
console.error(err); console.error(err);
} }
}); });
redis.del(val,function (err,ret) { redis.del(val, function (err, ret) {
if(err){ if (err) {
console.error(err); console.error(err);
} }
}); });
//通知用户下线 //通知用户下线
if(val != AppConfig.KEFUUUID){ if (val != AppConfig.KEFUUUID) {
redis.get(AppConfig.KEFUUUID,function (err,sid) { redis.get(AppConfig.KEFUUUID, function (err, sid) {
if(err){ if (err) {
console.error(err); console.error(err);
} }
if(sid){ if (sid) {
var info = { var info = {
"uid":val, "uid": val,
"name":'客户下线', "name": '客户下线',
"type":'offline' "type": 'offline'
}; };
io.to(sid).emit('update-users',info); io.to(sid).emit('update-users', info);
} }
}); });
redis.get('user-uuids',function (err,uuids) { redis.get('user-uuids', function (err, uuids) {
if(err){ if (err) {
console.error(err); console.error(err);
} }
if(uuids){ if (uuids) {
uuids =JSON.parse(uuids); uuids = JSON.parse(uuids);
}else{ } else {
uuids = []; uuids = [];
} }
val = parseInt(val); val = parseInt(val);
var idx = __uuids.indexOf(val); var idx = __uuids.indexOf(val);
if( idx != -1){ if (idx != -1) {
__uuids.remove(val); __uuids.remove(val);
//uuids.splice(idx,1); //uuids.splice(idx,1);
var tmp = []; var tmp = [];
uuids.forEach(function (user) { uuids.forEach(function (user) {
if(user.uid != val){ if (user.uid != val) {
tmp.push(user); tmp.push(user);
} }
}); });
uuids = JSON.stringify(tmp); uuids = JSON.stringify(tmp);
redis.set('user-uuids',uuids,null,function (err,ret) { redis.set('user-uuids', uuids, null, function (err, ret) {
if(err){ if (err) {
console.error(err); console.error(err);
} }
}); });
@ -187,41 +192,42 @@ function ioServer(io) {
}); });
//重连事件 //重连事件
socket.on('reconnect', function() { socket.on('reconnect', function () {
console.log("重新连接到服务器"); console.log("重新连接到服务器");
}); });
//监听客户端发送的信息,实现消息转发到各个其他客户端 //监听客户端发送的信息,实现消息转发到各个其他客户端
socket.on('message',function(msg){ socket.on('message', function (msg) {
msgModel.add(msg.from_uid,msg.uid,msg.content,msg.chat_type,msg.image,function (err) { //保存到数据库
if(err){ msgModel.add(msg.from_uid, msg.uid, msg.content, msg.chat_type, msg.image, function (err) {
console.error(err); if (err) {
} console.error(err);
}
}); });
if(msg.type == msgType.messageType.public){ if (msg.type == msgType.messageType.public) {
var mg = { var mg = {
"uid" : msg.from_uid , "uid": msg.from_uid,
"content": msg.content, "content": msg.content,
"chat_type" : msg.chat_type?msg.chat_type:'text', "chat_type": msg.chat_type ? msg.chat_type : 'text',
"image":msg.image "image": msg.image
}; };
socket.broadcast.emit("message",mg); socket.broadcast.emit("message", mg);
}else if(msg.type == msgType.messageType.private){ } else if (msg.type == msgType.messageType.private) {
var uid = msg.uid; var uid = msg.uid;
redis.get(uid,function (err,sid) { redis.get(uid, function (err, sid) {
if(err){ if (err) {
console.error(err); console.error(err);
} }
if(sid){ if (sid) {
//给指定的客户端发送消息 //给指定的客户端发送消息
var mg = { var mg = {
"uid" : msg.from_uid, "uid": msg.from_uid,
"content": msg.content, "content": msg.content,
"chat_type" : msg.chat_type?msg.chat_type:'text', "chat_type": msg.chat_type ? msg.chat_type : 'text',
"image":msg.image "image": msg.image
}; };
io.to(sid).emit('message',mg); io.to(sid).emit('message', mg);
} }
}); });
} }
@ -230,30 +236,30 @@ function ioServer(io) {
this.updateOnlieCount = function (isConnect) { this.updateOnlieCount = function (isConnect) {
//记录在线客户连接数 //记录在线客户连接数
redis.get('online_count',function (err,val) { redis.get('online_count', function (err, val) {
if(err){ if (err) {
console.error(err); console.error(err);
} }
if(!val){ if (!val) {
val = 0; val = 0;
} }
if(typeof val == 'string'){ if (typeof val == 'string') {
val = parseInt(val); val = parseInt(val);
} }
if(isConnect){ if (isConnect) {
val += 1; val += 1;
}else{ } else {
val -= 1; val -= 1;
if(val<=0){ if (val <= 0) {
val = 0; val = 0;
} }
} }
console.log('当前在线人数:'+val); console.log('当前在线人数:' + val);
io.sockets.emit('update_online_count', { online_count: val }); io.sockets.emit('update_online_count', {online_count: val});
redis.set('online_count',val,null,function (err,ret) { redis.set('online_count', val, null, function (err, ret) {
if(err){ if (err) {
console.error(err); console.error(err);
} }
}); });

View File

@ -93,12 +93,13 @@ $(function(){
} }
const gongHao = 10002;
$("#btnSend").click(function(){ $("#btnSend").click(function(){
var msg = $("#textarea").val(); var msg = $("#textarea").val();
if(msg){ if(msg){
var msg_sender = { var msg_sender = {
"type":'private', "type":'private',
"uid":'chat-kefu-admin', "uid":'chat-admin-' + gongHao,
"content":msg, "content":msg,
"from_uid":uuid, "from_uid":uuid,
"chat_type":'text' "chat_type":'text'
@ -195,10 +196,11 @@ $(function(){
uuid = fp1.get(); uuid = fp1.get();
console.log('连接成功...'+uuid); console.log('连接成功...'+uuid);
var ip = $("#keleyivisitorip").html(); var ip = $("#keleyivisitorip").text();
var msg = { var msg = {
"uid" : uuid, "uid" : uuid,
"ip" : ip "ip" : ip,
"gongHao":gongHao
}; };
socket.emit('login', msg); socket.emit('login', msg);
get_message(uuid); get_message(uuid);

View File

@ -322,6 +322,10 @@ layui.use(['layer', 'form', 'jquery'], function () {
shade :0.7, shade :0.7,
value: '' value: ''
}, function (username, index, elem) { }, function (username, index, elem) {
if(!username){
showLoginView();
return;
}
$.post('/admin/login', {username}, (res) => { $.post('/admin/login', {username}, (res) => {
if (res.code != 200) { if (res.code != 200) {
layer.msg(res.message); layer.msg(res.message);
@ -330,7 +334,7 @@ layui.use(['layer', 'form', 'jquery'], function () {
layer.msg('登录成功'); layer.msg('登录成功');
layer.closeAll(); layer.closeAll();
console.log(res); console.log(res);
// location.reload(); location.reload();
}, 'json').fail(() => { }, 'json').fail(() => {
layer.msg('登录异常请重试') layer.msg('登录异常请重试')
}) })
@ -339,6 +343,7 @@ layui.use(['layer', 'form', 'jquery'], function () {
if (!data.username) { if (!data.username) {
showLoginView(); showLoginView();
} else { } else {
socket.connect();
init(); init();
get_users(); get_users();
} }

View File

@ -30,9 +30,18 @@ router.get('/admin/users', function (req, res, next) {
res.render('./server/users'); res.render('./server/users');
}); });
router.get('/admin/setup', function (req, res, next) { router.get('/admin/setup', async function (req, res, next) {
let data = getViewAdmin(req) let data = getViewAdmin(req);
res.render('./server/setup', data); if(!data.username){ // 没有登录则 直接跳转到首页
res.redirect('/admin');
return;
}
let info = await userModel.findByUserName(data.username);
if(!info){
res.redirect('/admin');return;
}
console.log(info);
res.render('./server/setup', info);
}); });
router.post('/admin/update', async (req, res, next) => { router.post('/admin/update', async (req, res, next) => {

View File

@ -1,5 +1,5 @@
var mongoose = require("mongoose"); var mongoose = require("mongoose");
const DB_URL = 'mongodb://127.0.0.1:27017/kefu'; const DB_URL = 'mongodb://192.168.10.80:27017/kefu';
mongoose.connect(DB_URL); mongoose.connect(DB_URL);
/** /**

View File

@ -5,8 +5,37 @@
</div> </div>
<script> <script>
//一般直接写在一个js文件中 //一般直接写在一个js文件中
layui.use(['element'], function(){ layui.use(['element', 'layer','jquery'], function () {
var element = layui.element; var element = layui.element;
const layer = layui.layer;
const $ = layui.jquery;
let showLoginView = () => {
layer.prompt({
formType: 0,
title: '请先输入要切换的工号',
btnAlign: 'c',
// btn: ['切换','取消'],
// closeBtn: 0,
value: data.username
}, function (username, index, elem) {
$.post('/admin/login', {username}, (res) => {
if (res.code != 200) {
layer.msg(res.message);
return;
}
layer.msg('登录成功');
layer.closeAll();
console.log(res);
location.reload();
}, 'json').fail(() => {
layer.msg('登录异常请重试')
})
});
}
$('a.change-username').on('click', function () {
showLoginView();
return false;
});
// element.on('nav(nav-admin)', function(ele){ // element.on('nav(nav-admin)', function(ele){
// $(ele).addClass("layui-this"); // $(ele).addClass("layui-this");
// }); // });

View File

@ -60,6 +60,7 @@
var data = { var data = {
username:'<%= username %>' username:'<%= username %>'
}; };
</script> </script>
</head> </head>
<body> <body>
@ -67,6 +68,6 @@
<li class="layui-nav-item admin-index"><a href="/admin">我的对话</a></li> <li class="layui-nav-item admin-index"><a href="/admin">我的对话</a></li>
<!--<li class="layui-nav-item admin-users"><a href="/admin/users">访客</a></li>--> <!--<li class="layui-nav-item admin-users"><a href="/admin/users">访客</a></li>-->
<li class="layui-nav-item admin-setup"><a href="/admin/setup">设置</a></li> <li class="layui-nav-item admin-setup"><a href="/admin/setup">设置</a></li>
<li class="layui-nav-item"><a href="##">切换工号</a></li> <li class="layui-nav-item"><a href="##" class="change-username">切换工号</a></li>
</ul> </ul>

View File

@ -2,17 +2,24 @@
<div class="layui-container" style="text-align: center;margin-top:3rem;"> <div class="layui-container" style="text-align: center;margin-top:3rem;">
<form class="layui-form form-update-info" action="/admin/update"> <form class="layui-form form-update-info" action="/admin/update">
<div class="layui-form-item">
<label class="layui-form-label">工号</label>
<div class="layui-input-block" style="text-align: left;line-height: 38px;font-weight: bold;">
<%=username%>
</div>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">昵称</label> <label class="layui-form-label">昵称</label>
<div class="layui-input-block"> <div class="layui-input-block">
<input type="text" name="nickname" required lay-verify="required" placeholder="请输入标题" autocomplete="off" <input type="text" name="nickname" required lay-verify="required" class="layui-input"
class="layui-input"> placeholder="请输入标题" autocomplete="off" value="<%=nickname%>">
</div> </div>
</div> </div>
<div class="layui-form-item layui-form-text"> <div class="layui-form-item layui-form-text">
<label class="layui-form-label">开场描述</label> <label class="layui-form-label">开场描述</label>
<div class="layui-input-block"> <div class="layui-input-block">
<textarea name="description" placeholder="在打开客服时自动发送的消息内容" class="layui-textarea"></textarea> <textarea name="description" placeholder="在打开客服时自动发送的消息内容"
class="layui-textarea"><%=description%></textarea>
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">