懒病拖延症啊

这么一个小小的问题
改了这么久
早知道就自己重新写了
This commit is contained in:
LittleBoy 2019-10-01 23:41:10 +08:00
parent 55cb20946f
commit 5fb1741713
11 changed files with 104 additions and 141 deletions

2
app.js
View File

@ -18,7 +18,7 @@ app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public // uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
// 日志 // 日志
app.use(logger('dev')); // app.use(logger('dev'));
app.use(bodyParser.json()); app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.urlencoded({ extended: false }));
// cookie // cookie

View File

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

View File

@ -20,11 +20,11 @@ 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);
@ -45,31 +45,37 @@ function ioServer(io) {
//如果不是客服登录 //如果不是客服登录
if (type != 'kefu') { if (type != 'kefu') {
let gongHao = msg.gongHao; let gongHao = msg.kefu_id;
console.log('new customer login process gongHao=>', gongHao) let location = Common.getIpLocation(msg.ip);
console.log('来自', location, '的客户连接并登录了处理客服gongHao=>', gongHao)
// 获取管理员的socket // 获取管理员的socket
try { try {
//获取管理员 socket //获取管理员 socket
let kefuData = await sessoionModel.find(gongHao); let kefuData = await sessoionModel.find(gongHao);
if (kefuData) { // 找到客服数据 if (kefuData) { // 找到客服数据
let location = Common.getIpLocation(msg.ip);
// let socket = socket.id; // let socket = socket.id;
// let type = 'customer'; // let type = 'customer';
// let kefu_id = gongHao; // let kefu_id = gongHao;
let clientInfo = { let clientInfo = {
"uid": uid, "uid": uid,
"name": location + ' 客户', "nickname": location + ' 客户',
"type": 'online' "type": 'online',
status: 1,
}; };
// 添加客户到 对应的客服 // 添加客户到 对应的客服
await sessoionModel.createOrUpdate({uid}, { await sessoionModel.createOrUpdate({uid}, (isCreate) => {
let data = {
uid, uid,
socket: socket.id, socket: socket.id,
type: 'customer',
kefu_id: gongHao, kefu_id: gongHao,
status: 1, status: 1
nickname: clientInfo.name, };
if (isCreate) {
data['type'] = 'customer';
data['nickname'] = clientInfo.name;
}
return data;
}) })
// 给管理员发送通知 // 给管理员发送通知
io.to(kefuData.socket).emit('update-users', clientInfo); io.to(kefuData.socket).emit('update-users', clientInfo);
@ -98,22 +104,22 @@ function ioServer(io) {
//断开事件 //断开事件
socket.on('disconnect', async function () { socket.on('disconnect', async function () {
console.log("与服务其断开");
// _self.updateOnlineCount(false); // _self.updateOnlineCount(false);
let user = socket['_user']; let user = socket['_user'];
if (user) { if (user) {
console.log("与服务其断开",user);
// 更新用户状态 // 更新用户状态
await sessoionModel.update(user.uid, {status: 0}); await sessoionModel.update(user.uid, {status: 0});
if (user.type == 'customer') { if (user.type == 'customer' && user.kefu_id) {
// 查找对应kf通知下线操作 // 查找对应kf通知下线操作
let kf_data = await sessoionModel.find(user.kefu_id); let kf_data = await sessoionModel.find(user.kefu_id);
if (kf_data && kf_data.status == 1) { // 客服在线才通知哟
var info = { if (kf_data && kf_data.status == 1) { // 客服在线才通知哟
"uid": user.uid, let info = {
"name": '客户下线', "uid":user.uid,
"type": 'offline' "type": 'offline',
"nickname":"",
status: 0
}; };
io.to(kf_data.socket).emit('update-users', info); io.to(kf_data.socket).emit('update-users', info);
} }
@ -167,7 +173,8 @@ function ioServer(io) {
}); });
this.updateOnlineCount = function (isConnect) { this.updateOnlineCount = function (isConnect) {
//记录在线客户连接数 return;
// 更新在线客户连接数
redis.get('online_count', function (err, val) { redis.get('online_count', function (err, val) {
if (err) { if (err) {
console.error(err); console.error(err);

View File

@ -37,11 +37,17 @@ module.exports = {
} }
try{ try{
if(session){ if(session){
if(typeof(data) == "function"){
data = data.call(this,false)
}
sessionModel.update(condition,data, (err, doc) => { sessionModel.update(condition,data, (err, doc) => {
if (err) fail(err); if (err) fail(err);
else success(doc); else success(doc);
}) })
}else{//新增 }else{//新增
if(typeof(data) == "function"){
data = data.call(this,true)
}
let model = new sessionModel(data); let model = new sessionModel(data);
model.save(data, (err, doc) => { model.save(data, (err, doc) => {
if (err) fail(err); if (err) fail(err);

View File

@ -97,7 +97,8 @@ a {
.msg-agent .bubble,.msg-bot .bubble { .msg-agent .bubble,.msg-bot .bubble {
color: #000; color: #000;
background-color: #fff; background-color: #fff;
border-left: 1px solid #f0f0f0; display: inline-block;
border: 1px solid #f0f0f0;
} }
.msg-agent .agent-avatar, .msg-bot .agent-avatar { .msg-agent .agent-avatar, .msg-bot .agent-avatar {

View File

@ -66,13 +66,13 @@
.message-agent-content{ .message-agent-content{
position: relative; position: relative;
float: right; float: right;
background-color: #f0f1f3; background-color: #6d92bb;
color: #161e26; color: #fff;
} }
.message-client-content{ .message-client-content{
position: relative; position: relative;
float: left ; float: left ;
background-color: #e7f4ff; background-color: #efefef;
color: #161e26; color: #161e26;
} }
@ -110,14 +110,21 @@
} }
.user-info{ .user-info{
height: 60px; /*height: 60px;*/
/*line-height: 60px;*/
background: #ffffff; background: #ffffff;
line-height: 60px;
font-size: 16px; font-size: 16px;
color: #767d85; color: #767d85;
cursor: pointer;
border-bottom: 1px solid #e9e9e9; border-bottom: 1px solid #e9e9e9;
position: relative;
}
.user-info .user-status{
background-color: #999;
margin-left:5px;
color: #fff;
display: none;
} }
.chat-user{ .chat-user{
overflow: auto; overflow: auto;
} }
@ -132,6 +139,7 @@
.user-info .user-name{ .user-info .user-name{
font-size: 12px; font-size: 12px;
padding:14px 0;
} }
.empty-status{ .empty-status{

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 69 KiB

View File

@ -55,7 +55,7 @@ $(function(){
tpl += '<div class="bubble rich-text-bubble">'+ tpl += '<div class="bubble rich-text-bubble">'+
'<span class="arrow-bg"></span>'+ '<span class="arrow-bg"></span>'+
'<span class="arrow"></span>'+ '<span class="arrow"></span>'+
'<div class="text">' + msg.content + '</div>'+ '<div class="text"></div>'+
'</div>'; '</div>';
}else if(msg.chat_type == "image"){ }else if(msg.chat_type == "image"){
tpl += ' <div class="msg-agent-img">' + tpl += ' <div class="msg-agent-img">' +
@ -66,7 +66,7 @@ $(function(){
} }
tpl += '</div>'+ tpl += '</div>'+
'</div>'; '</div>';
$(".msg-container").append(tpl); $(tpl).appendTo(".msg-container").find('.text').html(msg.content.replace(/\n/g,"<br>"));
} }
//聊天窗口自动滚到底 //聊天窗口自动滚到底
@ -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 () { $(".emoji-list li").click(function () {
var content = $("#textarea").val(); var content = $("#textarea").val();
$("#textarea").val(content + " " +$(this).html()+ " " ); $("#textarea").val(content + " " +$(this).html()+ " " );
@ -204,8 +136,8 @@ $(function(){
var msg = { var msg = {
"uid" : uuid, "uid" : uuid,
"ip" : ip, "ip" : ip,
"gongHao":gongHao, kefu_id:gongHao,
type:'c' type:'customer'
}; };
socket.emit('login', msg); socket.emit('login', msg);
get_message(uuid); get_message(uuid);

View File

@ -69,7 +69,7 @@ layui.use(['layer', 'form', 'jquery'], function () {
if (msg.chat_type == "text") { if (msg.chat_type == "text") {
html += ' <div class="message-agent-content message-content">\n' + html += ' <div class="message-agent-content message-content">\n' +
' <div>' + msg.content + '</div>\n' + ' <div class="message-content-wrapper"></div>\n' +
' </div>\n'; ' </div>\n';
} else if (msg.chat_type == "image") { } else if (msg.chat_type == "image") {
html += ' <div class="msg-agent-img">' + html += ' <div class="msg-agent-img">' +
@ -80,7 +80,8 @@ layui.use(['layer', 'form', 'jquery'], function () {
} }
html += ' </div>'; html += ' </div>';
$('#section-' + msg.uid).append(html); $(html).appendTo('#section-' + msg.uid).find('.message-content-wrapper').html(msg.content.replace(/\n/g,"<br>"));
// $().append(html);
} }
// 添加客户端消息 // 添加客户端消息
@ -114,19 +115,23 @@ layui.use(['layer', 'form', 'jquery'], function () {
} }
function insert_user_html(id, name) { function insert_user_html(id, name, u) {
var html = '<div class="user-info layui-row" id="' + id + '">\n' +
var html = '<div class="user-info layui-row" data-uid="' + id + '" id="' + id + '">\n' +
' <div class="layui-col-xs3 user-avatar">\n' + ' <div class="layui-col-xs3 user-avatar">\n' +
' <img src="/images/server/mine_fill_blue.png">\n' + ' <img src="/images/server/mine_fill' + (u.status == 1 ? '_blue' : '') + '.png">\n' +
' </div>\n' + ' </div>\n' +
' <div class="layui-col-xs8 user-name">' + name + '-' + id + '</div>\n' + ' <div class="layui-col-xs8 user-name">' +
' <span class="nickname">' + name + '</span>' +
' <span class="layui-badge user-status">已离线</span></div>\n' +
' <span class="layui-badge-dot layui-col-xs1 msg-tips"></span>' + ' <span class="layui-badge-dot layui-col-xs1 msg-tips"></span>' +
' </div>'; ' </div>';
$('.chat-user').append(html); $('.chat-user').append(html);
} }
//设置消息状态 //设置消息状态
function msg_sender_status(status) { function msg_sender_status() {
let status = $('.user-info.selected').length != 0
if (status) { if (status) {
$(".btnMsgSend").removeClass("layui-btn-disabled"); $(".btnMsgSend").removeClass("layui-btn-disabled");
$("#msg-send-textarea").removeAttr("disabled"); $("#msg-send-textarea").removeAttr("disabled");
@ -186,17 +191,17 @@ layui.use(['layer', 'form', 'jquery'], function () {
var data = data.data; var data = data.data;
data.forEach(function (user) { data.forEach(function (user) {
insert_user_html(user.uid, user.name + '#' + (uuids.length + 1)); insert_user_html(user.uid, user.nickname, user);
//创建聊天section //创建聊天section
insert_section(user.uid); insert_section(user.uid, user);
uuids.push(user.uid); uuids.push(user.uid);
}); });
if (data.length > 0 && !currentUUID) { if (data.length > 0 && !currentUUID) {
currentUUID = data[0].uid; currentUUID = data[0].uid; // 设置当前对话 客户为第一个
} }
$(".user-info").css("background", "#ffffff"); $(".user-info").css("background", "#ffffff");
$("#" + currentUUID).css("background", "#f2f3f5"); $("#" + currentUUID).css("background", "#f2f3f5").addClass('selected');
$(".user-section").hide(); $(".user-section").hide();
msg_sender_status(true); msg_sender_status(true);
$("#section-" + currentUUID).show(); $("#section-" + currentUUID).show();
@ -247,7 +252,7 @@ layui.use(['layer', 'form', 'jquery'], function () {
var msg = { var msg = {
"uid": data.username, "uid": data.username,
"ip": ip, "ip": ip,
type:'kefu' type: 'kefu'
}; };
socket.emit('login', msg); socket.emit('login', msg);
}); });
@ -261,36 +266,37 @@ layui.use(['layer', 'form', 'jquery'], function () {
//后端推送来消息时,更新用户 //后端推送来消息时,更新用户
socket.on('update-users', function (msg) { socket.on('update-users', function (msg) {
if (msg.type == 'offline') { if (msg.type == 'offline') { // 用户离线
//arrayRemove(uuids,msg.uid);
$(".chat-user #" + msg.uid + " .user-avatar img").attr("src", "/images/server/mine_fill.png"); $(".chat-user #" + msg.uid + " .user-avatar img").attr("src", "/images/server/mine_fill.png");
$("#section-" + msg.uid).hide(); // $("#section-" + msg.uid).hide();
//$(".chat-user").find("#"+msg.uid).remove(); $(".chat-user").find(`[data-uid=${msg.uid}]`).find('.user-status').show();
msg_sender_status(false); msg_sender_status(false);
} else if (msg.type == 'online') { } else if (msg.type == 'online') {
// 设置 当前用户
if (!currentUUID) { if (!currentUUID) {
currentUUID = msg.uid; currentUUID = msg.uid;
} }
if (currentUUID == uuid) { if (currentUUID == uuid) {
return false; return false;
} }
var index = uuids.indexOf(msg.uid); // 获取上线的用户
if (index == -1) { if (uuids.indexOf(msg.uid) == -1) {
uuids.push(msg.uid); 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);
} }
//没有新的用户
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");
$(".chat-user #" + msg.uid + " .user-avatar img").attr("src", "/images/server/mine_fill_blue.png"); userInfoEle.find('.user-status').hide();
} }
update_online_status(); update_online_status();
}); });
@ -305,7 +311,8 @@ layui.use(['layer', 'form', 'jquery'], function () {
$(document).on('click', '.user-info', function () { $(document).on('click', '.user-info', function () {
var uid = $(this).attr("id"); var uid = $(this).attr("id");
currentUUID = uid; currentUUID = uid;
$(".user-info").css("background", "#ffffff"); $(".user-info").css("background", "#ffffff").removeClass('selected');
$(this).addClass('selected');
$("#" + uid).css("background", "#f2f3f5"); $("#" + uid).css("background", "#f2f3f5");
$(".user-section").hide(); $(".user-section").hide();
$("#section-" + uid).show(); $("#section-" + uid).show();
@ -320,10 +327,10 @@ layui.use(['layer', 'form', 'jquery'], function () {
btnAlign: 'c', btnAlign: 'c',
btn: [' 登录 '], btn: [' 登录 '],
closeBtn: 0, closeBtn: 0,
shade :0.7, shade: 0.7,
value: '' value: ''
}, function (username, index, elem) { }, function (username, index, elem) {
if(!username){ if (!username) {
showLoginView(); showLoginView();
return; return;
} }
@ -341,6 +348,7 @@ layui.use(['layer', 'form', 'jquery'], function () {
}) })
}); });
} }
window.getUserData = get_users;
if (!data.username) { if (!data.username) {
showLoginView(); showLoginView();
} else { } else {
@ -348,4 +356,5 @@ layui.use(['layer', 'form', 'jquery'], function () {
init(); init();
get_users(); get_users();
} }
}); });

View File

@ -8,7 +8,7 @@ const model = require('./../model/session');
/* GET users listing. */ /* GET users listing. */
router.get('/', async function (req, res, next) { router.get('/', async function (req, res, next) {
try { 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 : []}); return res.send({code: 200, msg: '获取成功', data: data ? data : []});
} catch (e) { } catch (e) {
return res.send({code: 400, msg: '获取失败'}); return res.send({code: 400, msg: '获取失败'});