diff --git a/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/AgentAuditController.java b/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/AgentAuditController.java index 507b899d..751bf5ec 100644 --- a/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/AgentAuditController.java +++ b/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/AgentAuditController.java @@ -276,6 +276,11 @@ public class AgentAuditController extends Handler { if (agentUser != null) { view.addObject("curagentuser", agentUser); + + CousultInvite invite = OnlineUserProxy.consult(agentUser.getAppid(), agentUser.getOrgi()); + if (invite != null) { + view.addObject("ccaAisuggest", invite.isAisuggest()); + } view.addObject("inviteData", OnlineUserProxy.consult(agentUser.getAppid(), agentUser.getOrgi())); List agentUserTaskList = agentUserTaskRes.findByIdAndOrgi(id, orgi); if (agentUserTaskList.size() > 0) { diff --git a/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/AgentController.java b/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/AgentController.java index d7c509ed..06c2bfde 100644 --- a/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/AgentController.java +++ b/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/AgentController.java @@ -262,7 +262,7 @@ User logined = super.getUser(request); view.addObject( "agentUserList", agentUserRes.findByAgentnoAndOrgi(logined.getId(), logined.getOrgi(), - new Sort(Direction.DESC, "status"))); + new Sort(Direction.DESC, "status"))); List agentUserList = agentUserRes.findByUseridAndOrgi(userid, logined.getOrgi()); view.addObject( "curagentuser", agentUserList != null && agentUserList.size() > 0 ? agentUserList.get(0) : null); @@ -317,7 +317,7 @@ String id, String search, String condition - ) throws IOException, TemplateException { + ) throws IOException, TemplateException { String mainagentuserconter = "/apps/agent/mainagentusersearch"; ModelAndView view = request(super.createRequestPageTempletResponse(mainagentuserconter)); AgentUser agentUser = agentUserRes.findByIdAndOrgi(id, super.getOrgi(request)); @@ -386,6 +386,11 @@ if (agentUser != null) { view.addObject("curagentuser", agentUser); + + CousultInvite invite = OnlineUserProxy.consult(agentUser.getAppid(), agentUser.getOrgi()); + if (invite != null) { + view.addObject("aisuggest", invite.isAisuggest()); + } view.addObject("inviteData", OnlineUserProxy.consult(agentUser.getAppid(), agentUser.getOrgi())); List agentUserTaskList = agentUserTaskRes.findByIdAndOrgi(id, orgi); if (agentUserTaskList.size() > 0) { @@ -405,8 +410,8 @@ view.addObject( "agentUserMessageList", this.chatMessageRes.findByUsessionAndOrgi(agentUser.getUserid(), orgi, - new PageRequest(0, 20, Direction.DESC, - "updatetime"))); + new PageRequest(0, 20, Direction.DESC, + "updatetime"))); AgentService agentService = null; if (StringUtils.isNotBlank(agentUser.getAgentserviceid())) { agentService = this.agentServiceRes.findOne(agentUser.getAgentserviceid()); @@ -454,10 +459,10 @@ view.addObject("serviceCount", Integer .valueOf(this.agentServiceRes - .countByUseridAndOrgiAndStatus(agentUser - .getUserid(), orgi, - MainContext.AgentUserStatusEnum.END - .toString()))); + .countByUseridAndOrgiAndStatus(agentUser + .getUserid(), orgi, + MainContext.AgentUserStatusEnum.END + .toString()))); view.addObject("tagRelationList", tagRelationRes.findByUserid(agentUser.getUserid())); } @@ -519,7 +524,7 @@ map.addAttribute( "workOrdersList", dataExchange.getListDataByIdAndOrgi(contactsid, super.getUser(request).getId(), - super.getOrgi(request))); + super.getOrgi(request))); } map.addAttribute("contactsid", contactsid); } @@ -546,14 +551,14 @@ // 为该坐席分配访客 acdAgentService.assignVisitors(agentStatus.getAgentno(), orgi); acdWorkMonitor.recordAgentStatus(agentStatus.getAgentno(), - agentStatus.getUsername(), - agentStatus.getAgentno(), - logined.isAdmin(), // 0代表admin - agentStatus.getAgentno(), - MainContext.AgentStatusEnum.NOTREADY.toString(), - MainContext.AgentStatusEnum.READY.toString(), - MainContext.AgentWorkType.MEIDIACHAT.toString(), - orgi, null); + agentStatus.getUsername(), + agentStatus.getAgentno(), + logined.isAdmin(), // 0代表admin + agentStatus.getAgentno(), + MainContext.AgentStatusEnum.NOTREADY.toString(), + MainContext.AgentStatusEnum.READY.toString(), + MainContext.AgentWorkType.MEIDIACHAT.toString(), + orgi, null); return request(super.createRequestPageTempletResponse("/public/success")); } @@ -584,14 +589,14 @@ agentStatusProxy.broadcastAgentsStatus(orgi, "agent", "notready", agentStatus.getAgentno()); acdWorkMonitor.recordAgentStatus(agentStatus.getAgentno(), - agentStatus.getUsername(), - agentStatus.getAgentno(), - logined.isAdmin(), // 0代表admin - agentStatus.getAgentno(), - MainContext.AgentStatusEnum.READY.toString(), - MainContext.AgentStatusEnum.NOTREADY.toString(), - MainContext.AgentWorkType.MEIDIACHAT.toString(), - orgi, null); + agentStatus.getUsername(), + agentStatus.getAgentno(), + logined.isAdmin(), // 0代表admin + agentStatus.getAgentno(), + MainContext.AgentStatusEnum.READY.toString(), + MainContext.AgentStatusEnum.NOTREADY.toString(), + MainContext.AgentWorkType.MEIDIACHAT.toString(), + orgi, null); return request(super.createRequestPageTempletResponse("/public/success")); } @@ -695,7 +700,7 @@ } agentServiceRes.save(agentServiceList); return request(super - .createRequestPageTempletResponse("redirect:/agent/index.html")); + .createRequestPageTempletResponse("redirect:/agent/index.html")); } @@ -733,7 +738,7 @@ } return request(super - .createRequestPageTempletResponse("redirect:/agent/index.html")); + .createRequestPageTempletResponse("redirect:/agent/index.html")); } @RequestMapping({"/readmsg"}) diff --git a/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/IMController.java b/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/IMController.java index e56b6eff..600fda18 100644 --- a/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/IMController.java +++ b/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/IMController.java @@ -91,6 +91,9 @@ public class IMController extends Handler { @Value("${web.upload-path}") private String path; + @Value("${cskefu.settings.webim.visitor-separate}") + private Boolean channelWebIMVisitorSeparate; + @Autowired private StreamingFileRepository streamingFileRepository; @@ -166,6 +169,8 @@ public class IMController extends Handler { @Valid String title, @Valid String aiid) { ModelAndView view = request(super.createRequestPageTempletResponse("/apps/im/point")); + view.addObject("channelVisitorSeparate", channelWebIMVisitorSeparate); + final String sessionid = MainUtils.getContextID(request.getSession().getId()); logger.info("[point] session snsid {}, session {}", id, sessionid); @@ -957,7 +962,7 @@ public class IMController extends Handler { view.addObject("port", request.getServerPort()); view.addObject("schema", request.getScheme()); view.addObject("appid", appid); - + view.addObject("channelVisitorSeparate", channelWebIMVisitorSeparate); view.addObject("ip", MainUtils.md5(request.getRemoteAddr())); if (invite.isSkill() && invite.isConsult_skill_fixed()) { // 添加技能组ID diff --git a/contact-center/app/src/main/java/com/chatopera/cc/model/Chatbot.java b/contact-center/app/src/main/java/com/chatopera/cc/model/Chatbot.java index deac4622..5f5eb7f4 100644 --- a/contact-center/app/src/main/java/com/chatopera/cc/model/Chatbot.java +++ b/contact-center/app/src/main/java/com/chatopera/cc/model/Chatbot.java @@ -40,6 +40,7 @@ public class Chatbot { @Column(unique = true) private String snsAccountIdentifier; // 渠道唯一标识 private boolean enabled; // 当前是否被启用 + private boolean aisuggest; // 智能回复是否被启用 private String workmode; // 工作模式, 机器人优先还是人工客服优先 private Date createtime; @@ -84,6 +85,14 @@ public class Chatbot { this.enabled = enabled; } + public boolean isAisuggest() { + return aisuggest; + } + + public void setAisuggest(boolean botAutocomplete) { + this.aisuggest = botAutocomplete; + } + public String getPrimaryLanguage() { return primaryLanguage; } diff --git a/contact-center/app/src/main/java/com/chatopera/cc/model/CousultInvite.java b/contact-center/app/src/main/java/com/chatopera/cc/model/CousultInvite.java index 6b397b75..1bad2622 100644 --- a/contact-center/app/src/main/java/com/chatopera/cc/model/CousultInvite.java +++ b/contact-center/app/src/main/java/com/chatopera/cc/model/CousultInvite.java @@ -142,6 +142,7 @@ public class CousultInvite implements java.io.Serializable { private String aimsg; //AI欢迎信息,可以使用 HTML private String aisuccesstip;//AI服务连接成功的消息提示 private String ainame; //AI服务 昵称 + private boolean aisuggest; private String aiid; //默认的机器人 @@ -929,6 +930,14 @@ public class CousultInvite implements java.io.Serializable { this.consult_skill_fixed_id = consult_skill_fixed_id; } + public boolean isAisuggest() { + return aisuggest; + } + + public void setAisuggest(boolean aisuggest) { + this.aisuggest = aisuggest; + } + public boolean isWhitelist_mode() { return whitelist_mode; } diff --git a/contact-center/app/src/main/java/com/chatopera/cc/proxy/AgentServiceProxy.java b/contact-center/app/src/main/java/com/chatopera/cc/proxy/AgentServiceProxy.java index 5f56ace7..9accae84 100644 --- a/contact-center/app/src/main/java/com/chatopera/cc/proxy/AgentServiceProxy.java +++ b/contact-center/app/src/main/java/com/chatopera/cc/proxy/AgentServiceProxy.java @@ -105,8 +105,8 @@ public class AgentServiceProxy { orgi, MainContext.AgentUserStatusEnum.END.toString(), defaultSort - ) - ); + ) + ); if (StringUtils.isNotBlank(agentService.getAppid())) { map.addAttribute("snsAccount", snsAccountRes.findBySnsidAndOrgi(agentService.getAppid(), orgi)); @@ -200,6 +200,12 @@ public class AgentServiceProxy { final User logined) { view.addObject("curagentuser", agentUser); + CousultInvite invite = OnlineUserProxy.consult(agentUser.getAppid(), agentUser.getOrgi()); + if (invite != null) { + view.addObject("aisuggest", invite.isAisuggest()); + view.addObject("ccaAisuggest", invite.isAisuggest()); + } + // 客服设置 if (agentUser != null && StringUtils.isNotBlank(agentUser.getAppid())) { view.addObject("inviteData", OnlineUserProxy.consult(agentUser.getAppid(), orgi)); @@ -216,8 +222,8 @@ public class AgentServiceProxy { view.addObject( "agentUserMessageList", chatMessageRepository.findByUsessionAndOrgi(agentUser.getUserid(), logined.getOrgi(), - new PageRequest(0, 20, Sort.Direction.DESC, - "updatetime"))); + new PageRequest(0, 20, Sort.Direction.DESC, + "updatetime"))); // 坐席服务记录 AgentService agentService = null; @@ -227,7 +233,7 @@ public class AgentServiceProxy { /** * 获取关联数据 */ - if(agentService != null){ + if (agentService != null) { processRelaData(logined.getId(), orgi, agentService, map); } } @@ -239,9 +245,9 @@ public class AgentServiceProxy { // 标签,快捷回复等 view.addObject("serviceCount", Integer .valueOf(agentServiceRes - .countByUseridAndOrgiAndStatus(agentUser - .getUserid(), logined.getOrgi(), - MainContext.AgentUserStatusEnum.END.toString()))); + .countByUseridAndOrgiAndStatus(agentUser + .getUserid(), logined.getOrgi(), + MainContext.AgentUserStatusEnum.END.toString()))); view.addObject("tagRelationList", tagRelationRes.findByUserid(agentUser.getUserid())); } diff --git a/contact-center/app/src/main/resources/application.properties b/contact-center/app/src/main/resources/application.properties index 8b8becb2..e85e7ef3 100644 --- a/contact-center/app/src/main/resources/application.properties +++ b/contact-center/app/src/main/resources/application.properties @@ -186,6 +186,12 @@ cskefu.callout.watch.interval=60000 ############################################## bot.baseurl=https://bot.chatopera.com +############################################## +# 业务功能相关设置 +############################################## +# 是否开启渠道访客独立 https://gitlab.chatopera.com/chatopera/cosinee/issues/838 +cskefu.settings.webim.visitor-separate=false + ############################################## # Skype渠道集成配置 ############################################## diff --git a/contact-center/app/src/main/resources/static/im/css/ukefu.css b/contact-center/app/src/main/resources/static/im/css/ukefu.css index 05c8ce53..3b0d87f5 100644 --- a/contact-center/app/src/main/resources/static/im/css/ukefu.css +++ b/contact-center/app/src/main/resources/static/im/css/ukefu.css @@ -352,10 +352,10 @@ input,textarea{ background-color: #c7dcfa !important; } .chatting-left div.chat-content img{ - max-width:460px; + max-width:100%; } .chatting-right div.chat-content img{ - max-width:460px; + max-width:100%; } .chatting-left div.chat-content a{ color:#4665d4; diff --git a/contact-center/app/src/main/resources/static/js/CSKeFu_IM.v1.js b/contact-center/app/src/main/resources/static/js/CSKeFu_IM.v1.js index ec8519b6..af83d887 100644 --- a/contact-center/app/src/main/resources/static/js/CSKeFu_IM.v1.js +++ b/contact-center/app/src/main/resources/static/js/CSKeFu_IM.v1.js @@ -52,6 +52,9 @@ $(document).ready(function(){ multiMediaDialogWin.Proxy.newAgentUserMessage(data,"agent"); if(data.type == 'message'){ WebIM.audioplayer('audioplane', newmessage, false); // 播放 + if(multiMediaDialogWin.isAisuggest && multiMediaDialogWin.isAisuggest == "true"){ + multiMediaDialogWin.Proxy.quickReply(data,"agent"); + } } }else{ //来电弹屏 @@ -74,6 +77,9 @@ $(document).ready(function(){ customerChatAudit.Proxy.newAgentUserMessage(data,"cca"); if(data.type == 'message'){ WebIM.audioplayer('audioplane', newmessage, false); // 播放 + if(customerChatAudit.isCcaAisuggest && customerChatAudit.isCcaAisuggest == "true"){ + customerChatAudit.Proxy.quickReply(data,"cca"); + } } } }).on('audit_new', function(data){ diff --git a/contact-center/app/src/main/resources/static/js/cskefu.js b/contact-center/app/src/main/resources/static/js/cskefu.js index 8ecd1ff5..bc707c76 100644 --- a/contact-center/app/src/main/resources/static/js/cskefu.js +++ b/contact-center/app/src/main/resources/static/js/cskefu.js @@ -1,4 +1,4 @@ -var layer , iframe , layerwin , cursession ; +var layer , iframe , layerwin , cursession ; $(document).ready(function(){ var hide ; $('.dropdown-menu').on("click" , function(){ @@ -333,7 +333,6 @@ var Proxy = { var newlist = template($('#message_tpl').html(), {data: data}) var nodeMeassage = $(newlist); nodeMeassage.find(".iconclick").click(function () { - console.log("点击标注") if($(this).attr('name') == 'nolabe'){ $(this).html('') $(this).css('color','#46cad4') @@ -366,6 +365,62 @@ var Proxy = { } } }, + quickReply:function(data,type){ + if(data.usession == cursession){ + if(data.message!=""){ + restApiRequest({ + silent: true, + path: 'chatbot', + data: { + ops: 'faq', + snsaccountid: data.appid , + userId:data.userid, + textMessage:data.message + } + }).then(function(result){ + if(result.rc === 0){ + if(result.data.length>0){ + type == "agent" ? $("#quickReplyBox").html("") : $("#ccaQuickReplyBox").html("") ; + $.each(sortByKey(result.data,'score'),function(i,n){ + var li = '
  • \n' + + '
    问题:'+result.data[i].post+'
    \n' + + '
    \n' + + '

    答案:'+result.data[i].reply_plain_text+'

    \n' + + ' \n' + + '
    \n' + + '
  • ' + type == "agent" ? $("#quickReplyBox").append(li) : $("#ccaQuickReplyBox").append(li) ; + if(i>4){ + return false; + } + }); + if(!$("#robot").hasClass('layui-this')){ + $("#dot").css("display","inline-block") + } + }else{ + type == "agent" ? $("#quickReplyBox").html("") : $("#ccaQuickReplyBox").html("") ; + $("#dot").css("display","none") + var liNone = '
  • \n' + + '
    \n' + + ' \n' + + '
    在知识库中未得到相关问题
    \n' + + '
    \n' + + '
  • ' + type == "agent" ? $("#quickReplyBox").html(liNone) : $("#ccaQuickReplyBox").html(liNone) ; + } + }else{ + type == "agent" ? $("#quickReplyBox").html("") : $("#ccaQuickReplyBox").html("") ; + $("#dot").css("display","none") + } + }, function(error){ + console.log("error", error); + // 服务器异常 + top.layer.msg('服务器抽风,请稍后再试!',{icon: 2, time: 3000}) + }) + + } + } + }, endAgentUserService:function(data){ if($('#tip_message_'+data.userid).length >0){ if(data.channel){ diff --git a/contact-center/app/src/main/resources/templates/apps/agent/index.html b/contact-center/app/src/main/resources/templates/apps/agent/index.html index ad15d0f9..3fd43dba 100644 --- a/contact-center/app/src/main/resources/templates/apps/agent/index.html +++ b/contact-center/app/src/main/resources/templates/apps/agent/index.html @@ -1,6 +1,7 @@ +
    @@ -59,6 +59,15 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
    +
    @@ -71,7 +80,7 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura }
    @@ -157,6 +213,12 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
    • 访客
    • + <#if aisuggest?? && aisuggest == true> +
    • + 智能机器人 + +
    • +
    • 历史
    • 搜索历史消息
    • <#if models?seq_contains("workorders")> @@ -260,6 +322,27 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
    +<#if aisuggest?? && aisuggest == true> +
    +
    +
    +

    + 知识库快捷 +

    +
    +
    +
      +
    • +
      + +
      未触发知识库查询
      +
      +
    • +
    +
    +
    +
    +
    @@ -418,12 +501,21 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura color: #00a65a; font-weight: bold; } + .nowrap{ + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: calc(100% - 40px); + } + +
    @@ -56,6 +56,15 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
    +
    @@ -142,6 +151,53 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura }); // }); KindEditor.options.cssData = "body { font-size: 15px; font-family:'Microsoft Yahei', 'Helvetica', 'Simsun', 'Arial';}"; + var agentEnterInput = $("iframe").contents().find("body"); + agentEnterInput.keyup(function(event){ + if(isCcaAisuggest && isCcaAisuggest == "true"){ + debouncefun(); + } + }) + var debouncefun = _.debounce(agentQuickReply,500) + function agentQuickReply() { + restApiRequest({ + silent: true, + path: 'chatbot', + data: { + ops: 'faq', + snsaccountid: "<#if curagentuser??>${curagentuser.appid!''}", + userId:"<#if curagentuser??>${curagentuser.userid!''}", + textMessage:editor.html() + } + }).then(function(result){ + if(result.rc === 0){ + if(result.data.length > 0){ + $("#ccaQuickReplyAgentBox").html(""); + $.each(sortByKey(result.data,'score'),function(i,n){ + var li = '
  • \n' + + '
    问题:'+result.data[i].post+'
    \n' + + '
    \n' + + '

    答案:'+result.data[i].reply_plain_text+'

    \n' + + ' \n' + + '
    \n' + + '
  • ' + $("#ccaQuickReplyAgentBox").append(li); + if(i>4){ + return false; + } + }); + showOrHide('block') + }else{ + showOrHide('none') + } + }else{ + showOrHide('none') + } + }, function(error){ + console.log("error", error); + // 服务器异常 + top.layer.msg('服务器抽风,请稍后再试!',{icon: 2, time: 3000}) + }) + } });
    @@ -154,6 +210,12 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
    • 访客
    • + <#if ccaAisuggest?? && ccaAisuggest == true> +
    • + 智能机器人 + +
    • +
    • 历史
    • 搜索历史消息
    • <#if models?seq_contains("workorders")> @@ -264,6 +326,28 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
    +<#if ccaAisuggest?? && ccaAisuggest == true> +
    +
    +
    +

    + 知识库快捷 +

    +
    +
    +
      +
    • +
      + +
      未触发知识库查询
      +
      +
    • +
    +
    +
    +
    + +
    @@ -422,12 +506,19 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura color: #00a65a; font-weight: bold; } - - + .nowrap{ + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: calc(100% - 40px); + } -