diff --git a/app.js b/app.js
index eff163b..5e703ab 100644
--- a/app.js
+++ b/app.js
@@ -18,7 +18,7 @@ app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
// 日志
-app.use(logger('dev'));
+// app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// cookie
diff --git a/config.js b/config.js
index 570b289..9740898 100644
--- a/config.js
+++ b/config.js
@@ -1,5 +1,5 @@
const APP = {
- "KF_PREFIX":'chat-admin-',
+ "KF_PREFIX":'',
"QINIU":{
"accessKey":"your access key",
"secretKey":"your secret key"
diff --git a/io/io.js b/io/io.js
index dbba9c4..76b723a 100644
--- a/io/io.js
+++ b/io/io.js
@@ -20,11 +20,11 @@ function ioServer(io) {
var __uuids = [];
//初始化连接人数
- redis.set('online_count', 0, null, function (err, ret) {
- if (err) {
- console.error(err);
- }
- });
+ // redis.set('online_count', 0, null, function (err, ret) {
+ // if (err) {
+ // console.error(err);
+ // }
+ // });
Array.prototype.remove = function (val) {
var index = this.indexOf(val);
@@ -45,31 +45,37 @@ function ioServer(io) {
//如果不是客服登录
if (type != 'kefu') {
- let gongHao = msg.gongHao;
- console.log('new customer login process gongHao=>', gongHao)
+ let gongHao = msg.kefu_id;
+ let location = Common.getIpLocation(msg.ip);
+ console.log('来自', location, '的客户连接并登录了处理客服gongHao=>', gongHao)
// 获取管理员的socket
try {
//获取管理员 socket
let kefuData = await sessoionModel.find(gongHao);
if (kefuData) { // 找到客服数据
- let location = Common.getIpLocation(msg.ip);
// let socket = socket.id;
// let type = 'customer';
// let kefu_id = gongHao;
let clientInfo = {
"uid": uid,
- "name": location + ' 客户',
- "type": 'online'
+ "nickname": location + ' 客户',
+ "type": 'online',
+ status: 1,
};
// 添加客户到 对应的客服
- await sessoionModel.createOrUpdate({uid}, {
- uid,
- socket: socket.id,
- type: 'customer',
- kefu_id: gongHao,
- status: 1,
- nickname: clientInfo.name,
+ await sessoionModel.createOrUpdate({uid}, (isCreate) => {
+ let data = {
+ uid,
+ socket: socket.id,
+ kefu_id: gongHao,
+ status: 1
+ };
+ if (isCreate) {
+ data['type'] = 'customer';
+ data['nickname'] = clientInfo.name;
+ }
+ return data;
})
// 给管理员发送通知
io.to(kefuData.socket).emit('update-users', clientInfo);
@@ -98,22 +104,22 @@ function ioServer(io) {
//断开事件
socket.on('disconnect', async function () {
- console.log("与服务其断开");
-
// _self.updateOnlineCount(false);
let user = socket['_user'];
if (user) {
+ console.log("与服务其断开",user);
// 更新用户状态
await sessoionModel.update(user.uid, {status: 0});
- if (user.type == 'customer') {
+ if (user.type == 'customer' && user.kefu_id) {
// 查找对应kf通知下线操作
let kf_data = await sessoionModel.find(user.kefu_id);
- if (kf_data && kf_data.status == 1) { // 客服在线才通知哟
- var info = {
- "uid": user.uid,
- "name": '客户下线',
- "type": 'offline'
+ if (kf_data && kf_data.status == 1) { // 客服在线才通知哟
+ let info = {
+ "uid":user.uid,
+ "type": 'offline',
+ "nickname":"",
+ status: 0
};
io.to(kf_data.socket).emit('update-users', info);
}
@@ -167,7 +173,8 @@ function ioServer(io) {
});
this.updateOnlineCount = function (isConnect) {
- //记录在线客户连接数
+ return;
+ // 更新在线客户连接数
redis.get('online_count', function (err, val) {
if (err) {
console.error(err);
diff --git a/model/session.js b/model/session.js
index a72a96b..e1e32bc 100644
--- a/model/session.js
+++ b/model/session.js
@@ -37,11 +37,17 @@ module.exports = {
}
try{
if(session){
+ if(typeof(data) == "function"){
+ data = data.call(this,false)
+ }
sessionModel.update(condition,data, (err, doc) => {
if (err) fail(err);
else success(doc);
})
}else{//新增
+ if(typeof(data) == "function"){
+ data = data.call(this,true)
+ }
let model = new sessionModel(data);
model.save(data, (err, doc) => {
if (err) fail(err);
diff --git a/public/css/client.css b/public/css/client.css
index 3df7cf8..d20ee45 100644
--- a/public/css/client.css
+++ b/public/css/client.css
@@ -97,7 +97,8 @@ a {
.msg-agent .bubble,.msg-bot .bubble {
color: #000;
background-color: #fff;
- border-left: 1px solid #f0f0f0;
+ display: inline-block;
+ border: 1px solid #f0f0f0;
}
.msg-agent .agent-avatar, .msg-bot .agent-avatar {
diff --git a/public/css/server.css b/public/css/server.css
index 19127dc..8e03f62 100644
--- a/public/css/server.css
+++ b/public/css/server.css
@@ -66,13 +66,13 @@
.message-agent-content{
position: relative;
float: right;
- background-color: #f0f1f3;
- color: #161e26;
+ background-color: #6d92bb;
+ color: #fff;
}
.message-client-content{
position: relative;
float: left ;
- background-color: #e7f4ff;
+ background-color: #efefef;
color: #161e26;
}
@@ -110,14 +110,21 @@
}
.user-info{
- height: 60px;
+ /*height: 60px;*/
+ /*line-height: 60px;*/
background: #ffffff;
- line-height: 60px;
font-size: 16px;
color: #767d85;
+ cursor: pointer;
border-bottom: 1px solid #e9e9e9;
+ position: relative;
+}
+.user-info .user-status{
+ background-color: #999;
+ margin-left:5px;
+ color: #fff;
+ display: none;
}
-
.chat-user{
overflow: auto;
}
@@ -132,6 +139,7 @@
.user-info .user-name{
font-size: 12px;
+ padding:14px 0;
}
.empty-status{
diff --git a/public/images/client.png b/public/images/client.png
index 78d1068..4407e47 100644
Binary files a/public/images/client.png and b/public/images/client.png differ
diff --git a/public/images/server.png b/public/images/server.png
index 7f13db7..2cfb160 100644
Binary files a/public/images/server.png and b/public/images/server.png differ
diff --git a/public/js/client/client.js b/public/js/client/client.js
index 1113e0a..5598f9d 100644
--- a/public/js/client/client.js
+++ b/public/js/client/client.js
@@ -55,7 +55,7 @@ $(function(){
tpl += '
'+
'
'+
'
'+
- '
' + msg.content + '
'+
+ '
'+
'
';
}else if(msg.chat_type == "image"){
tpl += ' ' +
@@ -66,7 +66,7 @@ $(function(){
}
tpl += '
'+
'';
- $(".msg-container").append(tpl);
+ $(tpl).appendTo(".msg-container").find('.text').html(msg.content.replace(/\n/g,"
"));
}
//聊天窗口自动滚到底
@@ -111,74 +111,6 @@ $(function(){
}
});
- $(".picture-upload").click(function () {
- var uploader = Qiniu.uploader({
- runtimes: 'html5,flash,html4', // 上传模式,依次退化
- browse_button: 'pickfiles', // 上传选择的点选按钮,必需
- uptoken_url: '/uptoken', // Ajax请求uptoken的Url,强烈建议设置(服务端提供)
- get_new_uptoken: false, // 设置上传文件的时候是否每次都重新获取新的uptoken
- domain: 'http://kefuimg.chinameyer.com/', // bucket域名,下载资源时用到,必需
- container: 'btn-uploader', // 上传区域DOM ID,默认是browser_button的父元素
- max_file_size: '10mb', // 最大文件体积限制
- flash_swf_url: 'path/of/plupload/Moxie.swf', //引入flash,相对路径
- max_retries: 3, // 上传失败最大重试次数
- dragdrop: false, // 开启可拖曳上传
- drop_element: 'btn-uploader', // 拖曳上传区域元素的ID,拖曳文件或文件夹后可触发上传
- chunk_size: '4mb', // 分块上传时,每块的体积
- auto_start: true, // 选择文件后自动上传,若关闭需要自己绑定事件触发上传
- unique_names: true,
- filters : {
- max_file_size : '10mb',
- prevent_duplicates: true,
- // Specify what files to browse for
- mime_types: [
- {title : "Image files", extensions : "jpg,gif,png,bmp"}, // 限定jpg,gif,png后缀上传
- ]
- },
- init: {
- 'FilesAdded': function(up, files) {
- plupload.each(files, function(file) {
- // 文件添加进队列后,处理相关的事情
- });
- },
- 'BeforeUpload': function(up, file) {
- // 每个文件上传前,处理相关的事情
- },
- 'UploadProgress': function(up, file) {
- // 每个文件上传时,处理相关的事情
- },
- 'FileUploaded': function(up, file, info) {
- // 查看简单反馈
- var domain = up.getOption('domain');
- var res = JSON.parse(info);
- var sourceLink = domain +"/"+ res.key;
-
- var msg_sender = {
- "type":'private',
- "uid":'chat-kefu-admin',
- "content":'图片消息',
- "from_uid":uuid,
- "chat_type":'image',
- "image":sourceLink
- };
- socket.emit('message', msg_sender);
- insert_client_html(msg_sender);
- scrollToBottom();
-
-
- },
- 'Error': function(up, err, errTip) {
- //上传出错时,处理相关的事情
- $.toast("上传失败");
- },
- 'UploadComplete': function() {
- //队列文件处理完毕后,处理相关的事情
- }
- }
- });
-
- });
-
$(".emoji-list li").click(function () {
var content = $("#textarea").val();
$("#textarea").val(content + " " +$(this).html()+ " " );
@@ -204,8 +136,8 @@ $(function(){
var msg = {
"uid" : uuid,
"ip" : ip,
- "gongHao":gongHao,
- type:'c'
+ kefu_id:gongHao,
+ type:'customer'
};
socket.emit('login', msg);
get_message(uuid);
diff --git a/public/js/server/index.js b/public/js/server/index.js
index 57d081d..3aca85b 100644
--- a/public/js/server/index.js
+++ b/public/js/server/index.js
@@ -69,7 +69,7 @@ layui.use(['layer', 'form', 'jquery'], function () {
if (msg.chat_type == "text") {
html += ' \n' +
- '
' + msg.content + '
\n' +
+ '
\n' +
'
\n';
} else if (msg.chat_type == "image") {
html += ' ' +
@@ -80,7 +80,8 @@ layui.use(['layer', 'form', 'jquery'], function () {
}
html += '
';
- $('#section-' + msg.uid).append(html);
+ $(html).appendTo('#section-' + msg.uid).find('.message-content-wrapper').html(msg.content.replace(/\n/g,"
"));
+ // $().append(html);
}
// 添加客户端消息
@@ -114,19 +115,23 @@ layui.use(['layer', 'form', 'jquery'], function () {
}
- function insert_user_html(id, name) {
- var html = '\n' +
+ function insert_user_html(id, name, u) {
+
+ var html = '
\n' +
'
\n' +
- '

\n' +
+ '
 + '.png)
\n' +
'
\n' +
- '
' + name + '-' + id + '
\n' +
+ '
' +
+ ' ' + name + '' +
+ ' 已离线
\n' +
'
' +
'
';
$('.chat-user').append(html);
}
//设置消息状态
- function msg_sender_status(status) {
+ function msg_sender_status() {
+ let status = $('.user-info.selected').length != 0
if (status) {
$(".btnMsgSend").removeClass("layui-btn-disabled");
$("#msg-send-textarea").removeAttr("disabled");
@@ -186,17 +191,17 @@ layui.use(['layer', 'form', 'jquery'], function () {
var data = data.data;
data.forEach(function (user) {
- insert_user_html(user.uid, user.name + '#' + (uuids.length + 1));
+ insert_user_html(user.uid, user.nickname, user);
//创建聊天section
- insert_section(user.uid);
+ insert_section(user.uid, user);
uuids.push(user.uid);
});
if (data.length > 0 && !currentUUID) {
- currentUUID = data[0].uid;
+ currentUUID = data[0].uid; // 设置当前对话 客户为第一个
}
$(".user-info").css("background", "#ffffff");
- $("#" + currentUUID).css("background", "#f2f3f5");
+ $("#" + currentUUID).css("background", "#f2f3f5").addClass('selected');
$(".user-section").hide();
msg_sender_status(true);
$("#section-" + currentUUID).show();
@@ -247,7 +252,7 @@ layui.use(['layer', 'form', 'jquery'], function () {
var msg = {
"uid": data.username,
"ip": ip,
- type:'kefu'
+ type: 'kefu'
};
socket.emit('login', msg);
});
@@ -261,36 +266,37 @@ layui.use(['layer', 'form', 'jquery'], function () {
//后端推送来消息时,更新用户
socket.on('update-users', function (msg) {
- if (msg.type == 'offline') {
- //arrayRemove(uuids,msg.uid);
+ if (msg.type == 'offline') { // 用户离线
$(".chat-user #" + msg.uid + " .user-avatar img").attr("src", "/images/server/mine_fill.png");
- $("#section-" + msg.uid).hide();
- //$(".chat-user").find("#"+msg.uid).remove();
+ // $("#section-" + msg.uid).hide();
+ $(".chat-user").find(`[data-uid=${msg.uid}]`).find('.user-status').show();
msg_sender_status(false);
} else if (msg.type == 'online') {
+ // 设置 当前用户
if (!currentUUID) {
currentUUID = msg.uid;
}
-
if (currentUUID == uuid) {
return false;
}
- var index = uuids.indexOf(msg.uid);
- if (index == -1) {
+ // 获取上线的用户
+ if (uuids.indexOf(msg.uid) == -1) {
uuids.push(msg.uid);
- insert_user_html(msg.uid, msg.name + '#' + (uuids.length + 1));
- //创建聊天section
- insert_section(msg.uid);
- } else {
- if ($(".chat-user").find("#" + msg.uid).length == 0) {
- insert_user_html(msg.uid, msg.name + '#' + (uuids.length + 1));
- //创建聊天section
- insert_section(msg.uid);
- }
}
-
- $(".chat-user #" + msg.uid + " .user-avatar img").attr("src", "/images/server/mine_fill_blue.png");
+ //没有新的用户
+ let userInfoEle = $(".chat-user").find(`[data-uid=${msg.uid}]`);
+ if (userInfoEle.length == 0) {
+ insert_user_html(msg.uid, msg.nickname, msg);
+ // 创建聊天section
+ insert_section(msg.uid);
+ userInfoEle = $(".chat-user").find(`[data-uid=${msg.uid}]`);
+ // insert_user_html(msg.uid, msg.name + '#' + (uuids.length + 1));
+ // //创建聊天section
+ // insert_section(msg.uid);
+ }
+ userInfoEle.find(".user-avatar img").attr("src", "/images/server/mine_fill_blue.png");
+ userInfoEle.find('.user-status').hide();
}
update_online_status();
});
@@ -305,7 +311,8 @@ layui.use(['layer', 'form', 'jquery'], function () {
$(document).on('click', '.user-info', function () {
var uid = $(this).attr("id");
currentUUID = uid;
- $(".user-info").css("background", "#ffffff");
+ $(".user-info").css("background", "#ffffff").removeClass('selected');
+ $(this).addClass('selected');
$("#" + uid).css("background", "#f2f3f5");
$(".user-section").hide();
$("#section-" + uid).show();
@@ -320,10 +327,10 @@ layui.use(['layer', 'form', 'jquery'], function () {
btnAlign: 'c',
btn: [' 登录 '],
closeBtn: 0,
- shade :0.7,
+ shade: 0.7,
value: ''
}, function (username, index, elem) {
- if(!username){
+ if (!username) {
showLoginView();
return;
}
@@ -341,6 +348,7 @@ layui.use(['layer', 'form', 'jquery'], function () {
})
});
}
+ window.getUserData = get_users;
if (!data.username) {
showLoginView();
} else {
@@ -348,4 +356,5 @@ layui.use(['layer', 'form', 'jquery'], function () {
init();
get_users();
}
+
});
\ No newline at end of file
diff --git a/routes/users.js b/routes/users.js
index 144bd20..92f594a 100644
--- a/routes/users.js
+++ b/routes/users.js
@@ -8,7 +8,7 @@ const model = require('./../model/session');
/* GET users listing. */
router.get('/', async function (req, res, next) {
try {
- let data = await model.findByCondition({type: 'customer', kefu_id: req.cookies.username});
+ let data = await model.findByCondition({type: 'customer',status:1, kefu_id: req.cookies.username});
return res.send({code: 200, msg: '获取成功', data: data ? data : []});
} catch (e) {
return res.send({code: 400, msg: '获取失败'});