Authored by 李奇

push失败代码恢复

... ... @@ -15,8 +15,7 @@ const clientService = require('../models/client-service');
const index = (req, res) => {
let type = 2;
let imgSize = '400x400';
// let encryptedUid = aes.encryptionUid(req.user.uid);
let encryptedUid = aes.encryptionUid(8040155);
let encryptedUid = aes.encryptionUid(req.user.uid);
let data = {
encryptedUid,
layout: false
... ...
... ... @@ -7,7 +7,7 @@
<div class="tab-content">
<div class="recent">
<span class="max">最近10笔订单</span>
<a class="more" href="/home/orders">MORE</a>
<a class="more" href="/home/orders" target="_blank">MORE</a>
</div>
{{> order-list}}
</div>
... ... @@ -18,7 +18,7 @@
</div>
</div>
<div class="right-footer qa">
<p class="more-q">没找到想问的问题?点此查看<a class="red" href="/help-center">更多问题~</a></p>
<p class="more-q">没找到想问的问题?点此查看<a class="red" href="/help" target="_blank">更多问题~</a></p>
<div class="chat-icon"></div>
</div>
</div>
... ...
/**
* 在线客服客户页
*
... ... @@ -10,6 +9,7 @@ var $ = require('yoho-jquery'),
uuid = require('uuid'),
emojiMap = require('./emoji-map'),
countdown = require('./countdown'),
tab = require('./tab-hidden'),
socketChat = require('./socket-chat'),
socketConf = require('./socket-config'),
common = require('../../../config/common');
... ... @@ -20,9 +20,13 @@ var cmEntity,
encryptedUid,
cursorPosition,
hasMore = true,
titleInterval,
docTitle = document.title,
$document = $(document),
$msgList = $('.msg-list'),
$msgEdit = $('.msg-edit'),
$leaveMsg = $('#leaveMsg'),
$close = $('.header .close'),
$sendOrder = $('.send-order'),
$sendImgInput = $('#sendImg'),
$history = $('.about-his.has-his'),
... ... @@ -33,7 +37,7 @@ var cmEntity,
$panelMainBody = $('.panel-main .main-body');
var processInfo = {
csId: 0, // 客服Id
manual: false,
promoter: 1, // 评论发起者 1:客户自己 2:客服
savedEval: false // 是否保存过评论
};
... ... @@ -67,24 +71,29 @@ for (key in urls) {
}
}
// (function() {
// var param = {
// return_type: 'jsonp',
// method: 'open.passport.get'
// };
// TODO 开发环境拿不到那个jsonp 这段代码仅供开发用
// socketChat.init(Object.assign(socketConf, {
//
// $.getJSON('//www.yohobuy.com/common/passport/?callback=?', param, function(jsonData) {
// if (jsonData && jsonData.data && jsonData.data.result !== -1) {
// if(jsonData.data.headIco) {
// socketConf.conversationMessage.userHead = jsonData.data.headIco;
// socketConf.conversationMessage.userName = window.getUser()[0];
// }
// onOpen: function() {
// console.log('websocket opened!');
// },
//
// onMessage: function(e) {
// var received = JSON.parse(e.data);
//
// // 原始配置信息用于重新连线
// originConf = JSON.parse(JSON.stringify(socketConf));
// cmEntity.conversationId = received.newConversationId !== 0 ?
// received.newConversationId :
// received.conversationId;
//
// // 保存过程中信息
// getMessage(received);
// },
//
// onClose: function() {
// console.log('websocket closed!');
// }
// });
// }());
//
// }));
/**
* 设置光标位置
... ... @@ -222,9 +231,8 @@ function toggleAnswer(e) {
/**
* 连线客服
*/
function connectService() {
function manualService() {
cmEntity.type = 2;
console.log(cmEntity);
socketChat.send(JSON.stringify(cmEntity));
}
... ... @@ -286,13 +294,16 @@ function enterSuccess(message) {
* @param message 内部消息对象
* @private
*/
function _linkSuccess(msgType, message) {
function linkSuccess(msgType, message) {
var OUT_SERVICE = 0,
LINE_UP = 1,
MANUAL_SERVICE = 2;
MANUAL_SERVICE = 2,
ADMIN_MANUAL_SERVICE = 3;
var liHtml;
var liHtml,
$iconEval = $('.icon.evaluate'),
$iconMs = $('.icon.manual-service');
switch (msgType) {
... ... @@ -323,6 +334,29 @@ function _linkSuccess(msgType, message) {
<span class="tip">${message.content}</span>
</p>
</div>`;
// 接入人工客服需要评价
processInfo.manual = true;
// 显示评价&隐藏人工
$iconEval.show();
$iconMs.hide();
break;
case ADMIN_MANUAL_SERVICE: // 3是管理员分配客服成功
liHtml =
`<div class="list-item">
<p class="push-tip">
<span class="tip">${message.content}</span>
</p>
</div>`;
// 接入人工客服需要评价
processInfo.manual = true;
// 显示评价&隐藏人工
$iconEval.show();
$iconMs.hide();
break;
default:
... ... @@ -339,7 +373,7 @@ function _linkSuccess(msgType, message) {
* @param text 文本
* @private
*/
function _emojiPrefix(text) {
function emojiPrefix(text) {
if (typeof text === 'string') {
return text.replace(/src="(\d{3}).gif"/g, 'src="/img/service/emoji/$1.gif"');
}
... ... @@ -351,10 +385,10 @@ function _emojiPrefix(text) {
* 处理客户消息
* @private
*/
function _handleCusMsg(rec, msgType, message) {
function handleCusMsg(rec, msgType, message) {
var liHtml;
message.newContent = _emojiPrefix(message.newContent);
message.newContent = emojiPrefix(message.newContent);
// 图片添加标签
if (msgType === 2) {
... ... @@ -372,8 +406,6 @@ function _handleCusMsg(rec, msgType, message) {
</div>
</div>`;
// targetItem.replaceWith(liHtml);
$msgList.append(liHtml);
$panelMainBody.scrollTop($panelMainBody[0].scrollHeight);
... ... @@ -383,7 +415,7 @@ function _handleCusMsg(rec, msgType, message) {
* 链接终端倒计时
* @private
*/
function _breakCountdown(message) {
function breakCountdown(message) {
var liHtml;
liHtml =
... ... @@ -401,25 +433,21 @@ function _breakCountdown(message) {
// 倒计时信息
countdown(message.newContent, $('.tip .countdown'));
}
/**
* 处理客服消息
* @private
*/
function _handleCsMsg(rec, msgType, message) {
function handleCsMsg(rec, msgType, message) {
var liHtml;
message.newContent = _emojiPrefix(message.newContent);
message.newContent = emojiPrefix(message.newContent);
if (msgType === 2) {
message.newContent =
`<img class="img-msg" src="${message.content}">`;
}
liHtml = `<div class="list-item guest">
<img src="${rec.csHead}" class="avatar">
<div class="item-detail">
... ... @@ -440,8 +468,8 @@ function _handleCsMsg(rec, msgType, message) {
function showEvalModal() {
var $evalModal = $('#makeEvaluation');
// 没有客服不可以评价
if (!processInfo.csId) {
// 没有接入人工
if (!processInfo.manual) {
return;
}
... ... @@ -457,10 +485,10 @@ function showEvalModal() {
html +=
`<div class="dis-row">
<span class="type" data-id="${data[i].id}">
<span class="type" data-id="${data[i].id}" data-content="${data[i].content}">
${data[i].content}
</span>
<span class="type" data-id="${data[i + 1].id}">
<span class="type" data-id="${data[i + 1].id}" data-content="${data[i].content}">
${data[i + 1].content}
</span>
</div>`;
... ... @@ -472,10 +500,10 @@ function showEvalModal() {
for (r = 1, i = 0; r <= ceilRows - 1; r++) {
html +=
`<div class="dis-row">
<span class="type" data-id="${data[i].id}">
<span class="type" data-id="${data[i].id}" data-content="${data[i].content}">
${data[i].content}
</span>
<span class="type" data-id="${data[i + 1].id}">
<span class="type" data-id="${data[i + 1].id}" data-content="${data[i].content}">
${data[i + 1].content}
</span>
</div>`;
... ... @@ -483,7 +511,7 @@ function showEvalModal() {
}
html +=
`<div class="dis-row">
<span class="type" data-id="${data[len - 1].id}">
<span class="type" data-id="${data[len - 1].id}" data-content="${data[i].content}">
${data[len - 1].content}
</span>
</div>`;
... ... @@ -516,15 +544,24 @@ function showEvalModal() {
* 处理收到消息
*/
function getMessage(rec) {
var tipTpl,
recType = rec.type,
message = rec.message,
msgType = message.type,
isHidden = tab.tabIsHidden(),
allTypes = socketConf.recType;
console.log('客户收到消息!', rec);
if (isHidden) {
titleInterval = setInterval(function() {
document.title = '您有新消息!';
setTimeout(function() {
document.title = docTitle;
}, 300);
}, 600);
}
switch (recType) {
case allTypes.ENTER:
... ... @@ -532,20 +569,20 @@ function getMessage(rec) {
break;
case allTypes.LINK_SUCCESS:
_linkSuccess(msgType, message);
linkSuccess(msgType, message);
break;
case allTypes.CU_SEND:
_handleCusMsg(rec, msgType, message);
handleCusMsg(rec, msgType, message);
break;
case allTypes.BREAK_TIME:
_breakCountdown(message);
breakCountdown(message);
break;
case allTypes.ROBOT_SEND:
rec.csName = rec.csName || '客服机器人';
message.newContent = message.newContent || '机器人暂时无法提供服务';
message.newContent = message.newContent || '非常抱歉,小YO不是很理解您的问题,您也可以联系<a>人工客服</a>';
tipTpl = `<div class="list-item guest">
<img src="/img/service/robot-avatar.png" class="avatar">
<div class="item-detail">
... ... @@ -559,20 +596,17 @@ function getMessage(rec) {
break;
case allTypes.CS_SEND:
// 处理客服消息
_handleCsMsg(rec, msgType, message);
handleCsMsg(rec, msgType, message);
break;
case allTypes.EVAL_INVITE:
// 客服发起
processInfo.promoter = 2;
showEvalModal();
break;
case allTypes.CS_CHATTING:
// 正在人工会话
csChatting(message);
break;
... ... @@ -618,10 +652,10 @@ function msgResolve(msgList) {
if (hasMore) {
for (item of msgList) {
item.message.newContent = _emojiPrefix(item.message.newContent);
item.message.newContent = emojiPrefix(item.message.newContent);
if (item.message.type === 2) {
item.message.newContent =
['<img class="msg-img" src="', item.message.newContent, '">'].join('');
['<img class="img-msg" src="', item.message.newContent, '">'].join('');
}
// 客户自己的消息
... ... @@ -683,30 +717,11 @@ function fetchHistoryMsg() {
});
}
// 初始化socket连接
socketChat.init(Object.assign(socketConf, {
onOpen: function() {
console.log('websocket opened!');
},
onMessage: function(e) {
var received = JSON.parse(e.data);
cmEntity.conversationId = received.newConversationId !== 0 ?
received.newConversationId :
received.conversationId;
// 保存过程中信息
processInfo.csId = received.csId;
getMessage(received);
},
onClose: function() {
console.log('websocket closed!');
}
}));
// tab页title重置
tab.tabVisible(function() {
document.title = docTitle;
clearInterval(titleInterval);
});
// 提交留言
$leaveMsg.find('.submit').click(function() {
... ... @@ -740,28 +755,35 @@ $makeEvalModal.find('.submit').click(function() {
star = mEval.find('.star.positive').length,
reasonTypes = mEval.find('.dis-row .type.chosen');
var reasonIds,
idArray = [];
var data = {
conversationId: cmEntity.conversationId,
encryptedUid: encryptedUid,
promoter: processInfo.promoter,
stars: star
};
var contents,
reasonIds,
idArray = [],
contentArray = [];
if (star < 4) {
$.each(reasonTypes, function(index, item) {
idArray.push($(item).data('id'));
contentArray.push($(item).data('content'));
});
reasonIds = idArray.join(':');
contents = contentArray.join(':');
data.reasonIds = reasonIds;
data.reasonMsgs = contents;
data.reasonMsg = reason;
}
$.ajax({
type: 'POST',
url: urls.makeEval,
data: {
conversationId: cmEntity.conversationId,
csId: processInfo.csId,
pid: cmEntity.platId,
promoter: processInfo.promoter,
reasonIds: reasonIds || '',
reasonMsgs: reason,
stars: star,
encryptedUid: encryptedUid
},
data: data,
success: function(res) {
if (res && res.code === 200) {
processInfo.promoter = 1;
... ... @@ -874,32 +896,35 @@ $sendImgInput.fileupload({
// 订单信息、常见问题
$rightHeadTab.on('click', function() {
var $el = $(this),
orderTab = $el.hasClass('order');
if ($el.hasClass('active')) {
$siblings = $el.siblings(),
$panRight = $('.panel-right'),
order = $el.hasClass('order'),
active = $el.hasClass('active'),
$qaUse = $panRight.find('.qa-use'),
$orderUse = $panRight.find('.order-use');
if (active) {
return;
}
if (orderTab) {
$('.right-head .tab.order').toggleClass('active');
$('.right-head .tab.qa').toggleClass('active');
$('.right-body.order').show();
$('.right-body.qa').hide();
$('.right-footer.qa').hide();
$el.addClass('active');
$siblings.removeClass('active');
if (order) {
$qaUse.hide();
$orderUse.show();
} else {
$('.right-head .tab.order').toggleClass('active');
$('.right-head .tab.qa').toggleClass('active');
$('.right-body.order').hide();
$('.right-body.qa').show();
$('.right-footer.qa').show();
$qaUse.show();
$orderUse.hide();
}
});
// 星评
$('.make-eval .stars .star').on('click', function() {
$document.on('click', '.make-eval .star', function() {
var el, i, len,
tag = $(this),
index = tag.index(),
$detailReason = $('.detail-reason'),
textEl = $('.make-eval .star-text'),
startList = $('.make-eval .stars .star');
... ... @@ -917,11 +942,13 @@ $('.make-eval .stars .star').on('click', function() {
el.index() > index && el.removeClass('positive');
}
index < 3 && $detailReason.show();
index >= 3 && $detailReason.hide();
textEl.text(starText[index]);
});
// 选择不满意类型
$(document).on('click', '.dis-row .type', function(e) {
$document.on('click', '.dis-row .type', function(e) {
$(e.target).toggleClass('chosen');
});
... ... @@ -958,7 +985,7 @@ $msgEdit.find('.util .icon').on('click', function(e) {
},
3: function() {
connectService();
manualService();
}
};
... ... @@ -969,13 +996,11 @@ $msgEdit.find('.util .icon').on('click', function(e) {
});
// 设置表情
$('.emoji-component .emoji').on('click', setEmoji);
$document.on('click', '.emoji-component .emoji', setEmoji);
// 重新连线
$msgList.on('click', '.reconnect', function() {
socketChat.init(Object.assign(originConf, {
onOpen: function() {
console.log('websocket opened!');
},
... ... @@ -1002,8 +1027,8 @@ $msgList.on('click', '.reconnect', function() {
$msgEdit.find('.send').on('click', sendMessage);
// 关闭聊天窗口
$('.header .close').click(function() {
if (processInfo.csId && !processInfo.savedEval) { // 没有保存过评论
$close.click(function() {
if (processInfo.manual && !processInfo.savedEval) { // 没有保存过评论
showEvalModal();
} else {
window.close();
... ... @@ -1023,8 +1048,8 @@ $msgList.on('click', '.msg-bubble .img-msg', function(e) {
msgZoomIn.fadeIn();
});
$('.img-zoom-in').on('click', function(e) {
$(e.currentTarget).fadeOut();
$document.on('click', '.img-zoom-in', function() {
$(this).fadeOut();
});
// 显示历史记录
... ... @@ -1038,13 +1063,44 @@ $panelMainBody.scroll(function() {
});
// 用户信息获取并初始化socket连接
(function() {
var param = {
return_type: 'jsonp',
method: 'open.passport.get'
};
$.getJSON('//www.yohobuy.com/common/passport/?callback=?', param, function(jsonData) {
if (jsonData && jsonData.data && jsonData.data.result !== -1) {
socketConf.conversationMessage.userHead = jsonData.data.headIco || socketConf.config.defaultUserHead;
socketConf.conversationMessage.userName = window.getUser()[0];
// 原始配置信息用于重新连线
originConf = JSON.parse(JSON.stringify(socketConf));
socketChat.init(Object.assign(socketConf, {
onOpen: function() {
console.log('websocket opened!');
},
onMessage: function(e) {
var received = JSON.parse(e.data);
cmEntity.conversationId = received.newConversationId !== 0 ?
received.newConversationId :
received.conversationId;
// 保存过程中信息
getMessage(received);
},
onClose: function() {
console.log('websocket closed!');
}
}));
}
});
}());
... ...
... ... @@ -9,6 +9,7 @@ var common = require('../../../config/common');
var config = {
servers: [common.domains.bjSocket],
defaultUserHead: '//img10.static.yhbimg.com/headimg/2013/11/28/09/01cae078abe5fe320c88cdf4c220212688.gif',
recType: {
ENTER: 1, // 用户进入
LINK_SUCCESS: 2, // 连线客服成功
... ... @@ -40,7 +41,7 @@ var config = {
sessionId: '',
encryptedUid: 0,
userHead: '//img10.static.yhbimg.com/headimg/2013/11/28/09/01cae078abe5fe320c88cdf4c220212688.gif', // 用户头像
userName: '18551982891', // 用户账号
userName: '18551982892', // 用户账号
csId: 0,
type: 1,
serviceSortId: 0,
... ...
/**
* 判断当前tab页是否可见
*
* @author: liqi <qi.li@yoho.cn>
* @date: 2016/11/26
*/
var state;
var isHidden;
var changeEvent;
function tabIsHidden() {
if (typeof document.hidden !== 'undefined') {
changeEvent = 'visibilitychange';
state = 'visibilityState';
} else if (typeof document.mozHidden !== 'undefined') {
changeEvent = 'mozvisibilitychange';
state = 'mozVisibilityState';
} else if (typeof document.msHidden !== 'undefined') {
changeEvent = 'msvisibilitychange';
state = 'msVisibilityState';
} else if (typeof document.webkitHidden !== 'undefined') {
changeEvent = 'webkitvisibilitychange';
state = 'webkitVisibilityState';
}
return document[state] === 'hidden';
}
function tabVisible(callback) {
isHidden = tabIsHidden();
document.addEventListener(changeEvent, function() {
if (!isHidden) {
if (callback) {
return callback();
}
}
}, false);
}
module.exports = {
tabVisible: tabVisible,
tabIsHidden: tabIsHidden
};
... ...