1
0
mirror of https://github.com/chatopera/cosin.git synced 2025-07-16 00:22:22 +08:00

#239 enhance visitor comment and fix entim bug with protocal detect

This commit is contained in:
Hai Liang Wang 2019-11-29 15:15:42 +08:00
parent a66f06ff2e
commit 2565ff8f6f
14 changed files with 68 additions and 35 deletions

View File

@ -105,11 +105,11 @@ public class ACDAgentService {
ctx.getAgentService().getStatus())) { ctx.getAgentService().getStatus())) {
// 通知消息到坐席 // 通知消息到坐席
MainContext.getPeerSyncIM().send(MainContext.ReceiverType.AGENT, MainContext.getPeerSyncIM().send(MainContext.ReceiverType.AGENT,
MainContext.ChannelType.WEBIM, MainContext.ChannelType.WEBIM,
ctx.getAppid(), ctx.getAppid(),
MainContext.MessageType.NEW, MainContext.MessageType.NEW,
ctx.getAgentService().getAgentno(), ctx.getAgentService().getAgentno(),
ctx, true); ctx, true);
} }
/** /**
@ -126,8 +126,8 @@ public class ACDAgentService {
} }
MainContext.getPeerSyncIM().send(MainContext.ReceiverType.VISITOR, MainContext.getPeerSyncIM().send(MainContext.ReceiverType.VISITOR,
MainContext.ChannelType.WEBIM, ctx.getAppid(), MainContext.ChannelType.WEBIM, ctx.getAppid(),
MainContext.MessageType.NEW, ctx.getOnlineUserId(), outMessage, true); MainContext.MessageType.NEW, ctx.getOnlineUserId(), outMessage, true);
} else { } else {
@ -149,7 +149,7 @@ public class ACDAgentService {
final String agentno, final String agentno,
final AgentUser agentUser, final AgentUser agentUser,
final String orgi final String orgi
) throws Exception { ) throws Exception {
final AgentStatus agentStatus = cache.findOneAgentStatusByAgentnoAndOrig(agentno, orgi); final AgentStatus agentStatus = cache.findOneAgentStatusByAgentnoAndOrig(agentno, orgi);
return pickupAgentUserInQueue(agentUser, agentStatus); return pickupAgentUserInQueue(agentUser, agentStatus);
} }
@ -171,8 +171,8 @@ public class ACDAgentService {
return; return;
} }
logger.info("[assignVisitors] agentStatus id {}, status {}, service {}/{}, skills {}, busy {}", logger.info("[assignVisitors] agentStatus id {}, status {}, service {}/{}, skills {}, busy {}",
agentStatus.getId(), agentStatus.getStatus(), agentStatus.getUsers(), agentStatus.getMaxusers(), agentStatus.getId(), agentStatus.getStatus(), agentStatus.getUsers(), agentStatus.getMaxusers(),
HashMapUtils.concatKeys(agentStatus.getSkills(), "|"), agentStatus.isBusy()); HashMapUtils.concatKeys(agentStatus.getSkills(), "|"), agentStatus.isBusy());
if ((!StringUtils.equals( if ((!StringUtils.equals(
MainContext.AgentStatusEnum.READY.toString(), agentStatus.getStatus())) || agentStatus.isBusy()) { MainContext.AgentStatusEnum.READY.toString(), agentStatus.getStatus())) || agentStatus.isBusy()) {
@ -276,12 +276,12 @@ public class ACDAgentService {
MainContext.ReceiverType.VISITOR, MainContext.ReceiverType.VISITOR,
MainContext.ChannelType.toValue(agentUser.getChannel()), agentUser.getAppid(), MainContext.ChannelType.toValue(agentUser.getChannel()), agentUser.getAppid(),
MainContext.MessageType.STATUS, agentUser.getUserid(), outMessage, true MainContext.MessageType.STATUS, agentUser.getUserid(), outMessage, true
); );
// 向坐席推送消息 // 向坐席推送消息
peerSyncIM.send(MainContext.ReceiverType.AGENT, MainContext.ChannelType.WEBIM, peerSyncIM.send(MainContext.ReceiverType.AGENT, MainContext.ChannelType.WEBIM,
agentUser.getAppid(), agentUser.getAppid(),
MainContext.MessageType.NEW, agentUser.getAgentno(), outMessage, true); MainContext.MessageType.NEW, agentUser.getAgentno(), outMessage, true);
} }
} catch (Exception ex) { } catch (Exception ex) {
logger.warn("[assignVisitors] fail to process service", ex); logger.warn("[assignVisitors] fail to process service", ex);
@ -395,15 +395,15 @@ public class ACDAgentService {
MainContext.ReceiverType.VISITOR, MainContext.ReceiverType.VISITOR,
MainContext.ChannelType.toValue(agentUser.getChannel()), agentUser.getAppid(), MainContext.ChannelType.toValue(agentUser.getChannel()), agentUser.getAppid(),
MainContext.MessageType.STATUS, agentUser.getUserid(), outMessage, true MainContext.MessageType.STATUS, agentUser.getUserid(), outMessage, true
); );
if (agentStatus != null) { if (agentStatus != null) {
// 坐席在线通知结束会话 // 坐席在线通知结束会话
outMessage.setChannelMessage(agentUser); outMessage.setChannelMessage(agentUser);
outMessage.setAgentUser(agentUser); outMessage.setAgentUser(agentUser);
peerSyncIM.send(MainContext.ReceiverType.AGENT, MainContext.ChannelType.WEBIM, peerSyncIM.send(MainContext.ReceiverType.AGENT, MainContext.ChannelType.WEBIM,
agentUser.getAppid(), agentUser.getAppid(),
MainContext.MessageType.END, agentUser.getAgentno(), outMessage, true); MainContext.MessageType.END, agentUser.getAgentno(), outMessage, true);
} }
break; break;
case PHONE: case PHONE:
@ -488,9 +488,15 @@ public class ACDAgentService {
final AgentUser agentUser, final AgentUser agentUser,
final String orgi, final String orgi,
final boolean finished) { final boolean finished) {
AgentService agentService = new AgentService(); AgentService agentService = new AgentService();
if (StringUtils.isNotBlank(agentUser.getAgentserviceid())) { if (StringUtils.isNotBlank(agentUser.getAgentserviceid())) {
agentService.setId(agentUser.getAgentserviceid()); AgentService existAgentService = agentServiceRes.findByIdAndOrgi(agentUser.getAgentserviceid(), orgi);
if (existAgentService != null) {
agentService = existAgentService;
} else {
agentService.setId(agentUser.getAgentserviceid());
}
} }
agentService.setOrgi(orgi); agentService.setOrgi(orgi);

View File

@ -665,12 +665,13 @@ public class IMController extends Handler {
} else { } else {
report = acdWorkMonitor.getAgentReport(invite.getOrgi()); report = acdWorkMonitor.getAgentReport(invite.getOrgi());
} }
boolean isLeavemsg = false;
if (report.getAgents() == 0 || if (report.getAgents() == 0 ||
(sessionConfig.isHourcheck() && (sessionConfig.isHourcheck() &&
!MainUtils.isInWorkingHours(sessionConfig.getWorkinghours()) && !MainUtils.isInWorkingHours(sessionConfig.getWorkinghours()) &&
invite.isLeavemessage())) { invite.isLeavemessage())) {
// 没有坐席在线进入留言 // 没有坐席在线进入留言
isLeavemsg = true;
boolean isInWorkingHours = MainUtils.isInWorkingHours(sessionConfig.getWorkinghours()); boolean isInWorkingHours = MainUtils.isInWorkingHours(sessionConfig.getWorkinghours());
map.addAttribute("isInWorkingHours", isInWorkingHours); map.addAttribute("isInWorkingHours", isInWorkingHours);
view = request(super.createRequestPageTempletResponse("/apps/im/leavemsg")); view = request(super.createRequestPageTempletResponse("/apps/im/leavemsg"));
@ -846,7 +847,7 @@ public class IMController extends Handler {
"/apps/im/chatbot/mobile")); // 智能机器人 移动端 "/apps/im/chatbot/mobile")); // 智能机器人 移动端
} }
} else { } else {
if (MobileDevice.isMobile(request.getHeader("User-Agent")) || StringUtils.isNotBlank(mobile)) { if (!isLeavemsg && (MobileDevice.isMobile(request.getHeader("User-Agent")) || StringUtils.isNotBlank(mobile))) {
view = request( view = request(
super.createRequestPageTempletResponse("/apps/im/mobile")); // WebIM移动端再次点选技能组 super.createRequestPageTempletResponse("/apps/im/mobile")); // WebIM移动端再次点选技能组
} }

View File

@ -4,7 +4,7 @@
<View alias="agentservice"> <View alias="agentservice">
<SQL> <SQL>
<![CDATA[ <![CDATA[
select * from uk_agentservice where 1 = 1 <#if skill?? && skill!=""> AND agentskill = '${skill!''}'</#if> <#if agent?? && agent!=""> AND agentno = '${agent!''}'</#if> <#if orgi?? && orgi!=""> AND orgi = '${orgi!''}'</#if> <#if begin?? && begin!=""> AND satistime >= str_to_date('${begin!''}', '%Y-%m-%d %H:%i:%s')</#if> <#if end?? && end!=""> AND satistime <= str_to_date('${end!''} 23:59:59', '%Y-%m-%d %H:%i:%s')</#if> select * from uk_agentservice where satisfaction = 1 <#if skill?? && skill!=""> AND agentskill = '${skill!''}'</#if> <#if agent?? && agent!=""> AND agentno = '${agent!''}'</#if> <#if orgi?? && orgi!=""> AND orgi = '${orgi!''}'</#if> <#if begin?? && begin!=""> AND satistime >= str_to_date('${begin!''}', '%Y-%m-%d %H:%i:%s')</#if> <#if end?? && end!=""> AND satistime <= str_to_date('${end!''} 23:59:59', '%Y-%m-%d %H:%i:%s')</#if>
]]> ]]>
</SQL> </SQL>
</View> </View>

View File

@ -536,6 +536,8 @@ input,textarea{
border: 1px solid #b2e5f9; border: 1px solid #b2e5f9;
float: right; float: right;
min-width: 25px; min-width: 25px;
max-width: 400px;
word-break: break-all;
} }
.chatting-right div.chat-content a{ .chatting-right div.chat-content a{
color:#4665d4; color:#4665d4;

View File

@ -79,9 +79,11 @@ KindEditor.plugin('image', function(K) {
//file //file
'<div class="ke-dialog-row">', '<div class="ke-dialog-row">',
hiddenElements.join(''), hiddenElements.join(''),
'<label style="width:60px;">' + lang.localUrl + '</label>', '<label style="width:52px;">' + lang.localUrl + '</label>',
'<input type="text" name="localUrl" class="ke-input-text" tabindex="-1" style="width:200px;" readonly="true" /> &nbsp;', '<input type="text" name="localUrl" class="ke-input-text" tabindex="-1" style="width:200px;" readonly="true" /> &nbsp;',
'<input type="button" class="ke-upload-button" value="' + lang.upload + '" />', '<input type="button" class="ke-upload-button" value="' + lang.upload + '" />',
'<div style="margin: 10px 0">图片支持png、jpeg、jpg</div>',
'<div>图片上限20MB</div>',
'</div>', '</div>',
'</form>', '</form>',
'</div>', '</div>',

View File

@ -21,14 +21,16 @@ KindEditor.plugin('insertfile', function(K) {
fileTitle = K.undef(options.fileTitle, ''), fileTitle = K.undef(options.fileTitle, ''),
clickFn = options.clickFn; clickFn = options.clickFn;
var html = [ var html = [
'<div style="padding:20px;">', '<div style="padding: 20px 20px 0 20px;">',
'<div class="ke-dialog-row">', '<div class="ke-dialog-row">',
'<label for="keUrl" style="width:60px;">' + lang.url + '</label>', '<label for="keUrl" style="width:52px;">' + lang.url + '</label>',
'<input type="text" id="keUrl" name="url" class="ke-input-text" style="width:160px;" /> &nbsp;', '<input type="text" id="keUrl" name="url" class="ke-input-text" style="width:160px;" /> &nbsp;',
'<input type="button" class="ke-upload-button" value="' + lang.upload + '" /> &nbsp;', '<input type="button" class="ke-upload-button" value="' + lang.upload + '" /> &nbsp;',
'<span class="ke-button-common ke-button-outer">', '<span class="ke-button-common ke-button-outer">',
'<input type="button" class="ke-button-common ke-button" name="viewServer" value="' + lang.viewServer + '" />', '<input type="button" class="ke-button-common ke-button" name="viewServer" value="' + lang.viewServer + '" />',
'</span>', '</span>',
'<div style="margin: 10px 0">文档支持doc/docx、xls/xlsx、pdf</div>',
'<div>文档上限20MB</div>',
'</div>', '</div>',
//title //title

View File

@ -79,9 +79,11 @@ KindEditor.plugin('image', function(K) {
//file //file
'<div class="ke-dialog-row">', '<div class="ke-dialog-row">',
hiddenElements.join(''), hiddenElements.join(''),
'<label style="width:60px;">' + lang.localUrl + '</label>', '<label style="width:52px;">' + lang.localUrl + '</label>',
'<input type="text" name="localUrl" class="ke-input-text" tabindex="-1" style="width:200px;" readonly="true" /> &nbsp;', '<input type="text" name="localUrl" class="ke-input-text" tabindex="-1" style="width:200px;" readonly="true" /> &nbsp;',
'<input type="button" class="ke-upload-button" value="' + lang.upload + '" />', '<input type="button" class="ke-upload-button" value="' + lang.upload + '" />',
'<div style="margin: 10px 0">图片支持png、jpeg、jpg</div>',
'<div>图片上限20MB</div>',
'</div>', '</div>',
'</form>', '</form>',
'</div>', '</div>',

View File

@ -21,14 +21,16 @@ KindEditor.plugin('insertfile', function(K) {
fileTitle = K.undef(options.fileTitle, ''), fileTitle = K.undef(options.fileTitle, ''),
clickFn = options.clickFn; clickFn = options.clickFn;
var html = [ var html = [
'<div style="padding:20px;">', '<div style="padding: 20px 20px 0 20px;">',
'<div class="ke-dialog-row">', '<div class="ke-dialog-row">',
'<label for="keUrl" style="width:60px;">' + lang.url + '</label>', '<label for="keUrl" style="width:52px;">' + lang.url + '</label>',
'<input type="text" id="keUrl" name="url" class="ke-input-text" style="width:160px;" /> &nbsp;', '<input type="text" id="keUrl" name="url" class="ke-input-text" style="width:160px;" /> &nbsp;',
'<input type="button" class="ke-upload-button" value="' + lang.upload + '" /> &nbsp;', '<input type="button" class="ke-upload-button" value="' + lang.upload + '" /> &nbsp;',
'<span class="ke-button-common ke-button-outer">', '<span class="ke-button-common ke-button-outer">',
'<input type="button" class="ke-button-common ke-button" name="viewServer" value="' + lang.viewServer + '" />', '<input type="button" class="ke-button-common ke-button" name="viewServer" value="' + lang.viewServer + '" />',
'</span>', '</span>',
'<div style="margin: 10px 0">文档支持doc/docx、xls/xlsx、pdf</div>',
'<div>文档上限20MB</div>',
'</div>', '</div>',
//title //title

View File

@ -2,6 +2,12 @@
<div class="uk-layui-form"> <div class="uk-layui-form">
<form class="layui-form" action="/apps/contacts/update.html" method="post"> <form class="layui-form" action="/apps/contacts/update.html" method="post">
<input type="hidden" name="id" value="${contacts.id!''}"> <input type="hidden" name="id" value="${contacts.id!''}">
<input type="hidden" name="wluid" value="${contacts.wluid!''}">
<input type="hidden" name="wlusername" value="${contacts.wlusername!''}">
<input type="hidden" name="wlcid" value="${contacts.wlcid!''}">
<input type="hidden" name="wlcompany_name" value="${contacts.wlcompany_name!''}">
<input type="hidden" name="wlsid" value="${contacts.wlsid!''}">
<input type="hidden" name="wlsystem_name" value="${contacts.wlsystem_name!''}">
<div class="layui-collapse"> <div class="layui-collapse">
<div class="layui-colla-item"> <div class="layui-colla-item">
<h2 class="layui-colla-title">基本信息</h2> <h2 class="layui-colla-title">基本信息</h2>

View File

@ -240,7 +240,7 @@
,element = layui.element(); //Tab的切换功能切换事件监听等需要依赖element模块 ,element = layui.element(); //Tab的切换功能切换事件监听等需要依赖element模块
}); });
var hostname = location.hostname ; var hostname = location.hostname ;
var socket = io.connect(top.schema+"://"+top.hostname+":"+top.port+"/im/ent?userid=${user.id!''!''}&orgi=${user.orgi!''}&contextid=${contextid!''}",{transports: ['websocket'], upgrade: false}); var socket = io.connect(location.protocol+"//"+top.hostname+":"+top.port+"/im/ent?userid=${user.id!''!''}&orgi=${user.orgi!''}&contextid=${contextid!''}",{transports: ['websocket'], upgrade: false});
socket.on('message', function(data) { socket.on('message', function(data) {
console.log('message', data); console.log('message', data);
data.createtime = formatDate(data.createtime); data.createtime = formatDate(data.createtime);

View File

@ -237,7 +237,7 @@
,element = layui.element(); //Tab的切换功能切换事件监听等需要依赖element模块 ,element = layui.element(); //Tab的切换功能切换事件监听等需要依赖element模块
}); });
var hostname = location.hostname ; var hostname = location.hostname ;
var socket = io.connect(top.schema+"://"+top.hostname+":"+top.port+"/im/ent?userid=${user.id!''!''}&orgi=${user.orgi!''}&contextid=${contextid!''}&group=${contextid!''}",{transports: ['websocket'], upgrade: false}); var socket = io.connect(location.protocol+"//"+top.hostname+":"+top.port+"/im/ent?userid=${user.id!''!''}&orgi=${user.orgi!''}&contextid=${contextid!''}&group=${contextid!''}",{transports: ['websocket'], upgrade: false});
socket.on('message', function(data) { socket.on('message', function(data) {
data.createtime = formatDate(data.createtime); data.createtime = formatDate(data.createtime);

View File

@ -201,7 +201,7 @@
$(this).children().first().html('&#xe61a;'); $(this).children().first().html('&#xe61a;');
} }
}) ; }) ;
var socket = io.connect(top.schema+"://"+top.hostname+":"+top.port+"/im/ent?userid=${user.id!''!''}&orgi=${user.orgi!''}"); var socket = io.connect(location.protocol+"//"+top.hostname+":"+top.port+"/im/ent?userid=${user.id!''!''}&orgi=${user.orgi!''}");
socket.on('connect',function(){ socket.on('connect',function(){
//service.sendRequestMessage(); //service.sendRequestMessage();
//output('<span id="callOutConnect-message">'+ new Date().format("yyyy-MM-dd hh:mm:ss") + ' 开始沟通' +'</span>' , 'message callOutConnect-message'); //output('<span id="callOutConnect-message">'+ new Date().format("yyyy-MM-dd hh:mm:ss") + ' 开始沟通' +'</span>' , 'message callOutConnect-message');

View File

@ -11,7 +11,7 @@
</div> </div>
<script> <script>
var hostname = location.hostname ; var hostname = location.hostname ;
var socket = io.connect(top.schema+"://"+top.hostname+":"+top.port+"/im/ent?userid=${user.id!''!''}&orgi=${user.orgi!''}"); var socket = io.connect(location.protocol+"//"+top.hostname+":"+top.port+"/im/ent?userid=${user.id!''!''}&orgi=${user.orgi!''}");
socket.on('connect',function(){ socket.on('connect',function(){
}) })
socket.on('message', function(data) { socket.on('message', function(data) {

View File

@ -20,7 +20,7 @@
<div id="header" class="theme${inviteData.consult_dialog_color!''}"> <div id="header" class="theme${inviteData.consult_dialog_color!''}">
<img src="<#if inviteData?? && inviteData.consult_dialog_logo??>/res/image.html?id=${inviteData.consult_dialog_logo?url}<#else>/images/logo.png</#if>" style="height:30px;padding:10px;"> <img src="<#if inviteData?? && inviteData.consult_dialog_logo??>/res/image.html?id=${inviteData.consult_dialog_logo?url}<#else>/images/logo.png</#if>" style="height:30px;padding:10px;">
</div> </div>
<div class="ukef-leavemsg-tip"> <div class="ukef-leavemsg-tip" style="padding-left: 15px">
<#if inviteData?? && inviteData.leavemessage> <#if inviteData?? && inviteData.leavemessage>
<#if sessionConfig?? && sessionConfig.hourcheck> <#if sessionConfig?? && sessionConfig.hourcheck>
<#if isInWorkingHours> <#if isInWorkingHours>
@ -83,3 +83,13 @@
</form> </form>
</body> </body>
</html> </html>
<style>
.leaveCon{
width: 100%;
max-width:550px ;
padding: 0 15px;
}
.leaveCon .txt01{
width: calc(100% - 130px);
}
</style>