mirror of
https://github.com/chatopera/cosin.git
synced 2025-07-28 12:32:15 +08:00
Closed https://github.com/chatopera/cosin/issues/251 enhance chatbot services for agent and visitor
This commit is contained in:
parent
6abacc646e
commit
ac7a346bf6
@ -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<AgentUserTask> agentUserTaskList = agentUserTaskRes.findByIdAndOrgi(id, orgi);
|
||||
if (agentUserTaskList.size() > 0) {
|
||||
|
@ -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<AgentUser> 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<AgentUserTask> 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"})
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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()));
|
||||
}
|
||||
|
||||
|
@ -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渠道集成配置
|
||||
##############################################
|
||||
|
@ -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;
|
||||
|
@ -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){
|
||||
|
@ -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 = ' <li class="ukefu-agentservice-list" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">\n' +
|
||||
' <div class="nowrap" title="'+result.data[i].post+'">问题:'+result.data[i].post+'</div>\n' +
|
||||
' <div style="color: #333">\n' +
|
||||
' <p class="nowrap" title="'+result.data[i].reply_plain_text+'" style="float: left ">答案:'+result.data[i].reply_plain_text+'</p>\n' +
|
||||
' <button style="float: right" class="layui-btn layui-btn-mini" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">选择</button>\n' +
|
||||
' </div>\n' +
|
||||
' </li>'
|
||||
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 = ' <li style="list-style: none;background-image: url();padding: 50px 0 50px;">\n' +
|
||||
' <div class="ukefu-empty" style="background: none">\n' +
|
||||
' <i class="layui-icon"></i>\n' +
|
||||
' <div style="">在知识库中未得到相关问题</div>\n' +
|
||||
' </div>\n' +
|
||||
' </li>'
|
||||
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){
|
||||
|
@ -1,6 +1,7 @@
|
||||
<link rel="stylesheet" href="/js/ztree/zTreeStyle/zTreeStyle.css">
|
||||
<script src="/js/ztree/jquery.ztree.all.min.js"></script>
|
||||
<script src="/js/utils.js"></script>
|
||||
<script src="/js/lodash-4.17.4.min.js"></script>
|
||||
<script src="/js/CSKeFu_Rest_Request.v1.js"></script>
|
||||
<!--<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>-->
|
||||
<script id="message_tpl" type="text/html">
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script language="javascript">
|
||||
cursession = "<#if curagentuser??>${curagentuser.userid!''}</#if>" ;
|
||||
var userid = "${curagentuser.userid!''}" , agentserviceid = "${curagentuser.agentserviceid!''}" , agentuserid = "${curagentuser.id}" , masscuragentuser = "${masscuragentuser}";
|
||||
var userid = "${curagentuser.userid!''}" , agentserviceid = "${curagentuser.agentserviceid!''}" , agentuserid = "${curagentuser.id}" , masscuragentuser = "${masscuragentuser}" , isAisuggest = "${aisuggest}";
|
||||
</script>
|
||||
|
||||
<div class="main-agentuser">
|
||||
@ -59,6 +59,15 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-bottom">
|
||||
<div id="agentAnswer" style="width: 50%;min-width:310px;height: 180px;border: 1px solid #eee;position: absolute;top: -180px;right:0px;background: #ffffff;display: none">
|
||||
<h1 class="site-h1" style="background-color:#EEEEEE;padding: 0px 10px" >知识库联想
|
||||
<i class="layui-icon" style="position: absolute;top: 0px;right: 5px;font-size:16px;z-index: 10" onclick="showOrHide('none')">ဆ</i>
|
||||
</h1>
|
||||
<div style="width: calc(100% - 19px);height: 129px;position: absolute;top: 31px;overflow-y: scroll;padding: 10px 10px">
|
||||
<ul class="info-list ukefu-quick-reply" style="width: 100%;height: auto" id="quickReplyAgentBox">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<textarea id="message" name="message"></textarea>
|
||||
@ -71,7 +80,7 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
|
||||
}
|
||||
</style>
|
||||
<script language="javascript">
|
||||
var editor , layer;
|
||||
var editor , layer;
|
||||
$(document).ready(function(){
|
||||
// KindEditor.ready(function(K) {
|
||||
var K = KindEditor;
|
||||
@ -145,6 +154,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(isAisuggest && isAisuggest == "true"){
|
||||
debouncefun();
|
||||
}
|
||||
})
|
||||
var debouncefun = _.debounce(agentQuickReply,500)
|
||||
function agentQuickReply() {
|
||||
restApiRequest({
|
||||
silent: true,
|
||||
path: 'chatbot',
|
||||
data: {
|
||||
ops: 'faq',
|
||||
snsaccountid: "<#if curagentuser??>${curagentuser.appid!''}</#if>",
|
||||
userId:"<#if curagentuser??>${curagentuser.userid!''}</#if>",
|
||||
textMessage:editor.html()
|
||||
}
|
||||
}).then(function(result){
|
||||
if(result.rc === 0){
|
||||
if(result.data.length > 0){
|
||||
$("#quickReplyAgentBox").html("");
|
||||
$.each(sortByKey(result.data,'score'),function(i,n){
|
||||
var li = ' <li class="ukefu-agentservice-list" style="font-size: 14px;line-height:22px" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">\n' +
|
||||
' <div class="nowrap" title="'+result.data[i].post+'">问题:'+result.data[i].post+'</div>\n' +
|
||||
' <div style="color: #333">\n' +
|
||||
' <p title="'+result.data[i].reply_plain_text+'" class="nowrap" style="float: left ">答案:'+result.data[i].reply_plain_text+'</p>\n' +
|
||||
' <button style="float: right" class="layui-btn layui-btn-mini" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">选择</button>\n' +
|
||||
' </div>\n' +
|
||||
' </li>'
|
||||
$("#quickReplyAgentBox").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})
|
||||
})
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
@ -157,6 +213,12 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
|
||||
<div class="layui-tab" style="margin-top:0px;">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">访客</li>
|
||||
<#if aisuggest?? && aisuggest == true>
|
||||
<li id="robot" onclick="$('#dot').css('display','none')">
|
||||
<span>智能机器人</span>
|
||||
<span id="dot" style=" width: 7px;height: 7px;background: red;-moz-border-radius: 50%;-webkit-border-radius: 50%;border-radius: 50%;position: absolute;top: 5px;display: none"></span>
|
||||
</li>
|
||||
</#if>
|
||||
<li>历史</li>
|
||||
<li>搜索历史消息</li>
|
||||
<#if models?seq_contains("workorders")>
|
||||
@ -260,6 +322,27 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
|
||||
</#if>
|
||||
</div>
|
||||
|
||||
<#if aisuggest?? && aisuggest == true>
|
||||
<div class="layui-tab-item">
|
||||
<div class="box">
|
||||
<div class="box-title">
|
||||
<h1 class="site-h1" style="background-color:#EEEEEE;">
|
||||
知识库快捷
|
||||
</h1>
|
||||
</div>
|
||||
<div class="box-body" style="padding:0px 10px;">
|
||||
<ul class="info-list ukefu-quick-reply" id="quickReplyBox">
|
||||
<li style="list-style: none;background-image: url();padding: 50px 0 50px;">
|
||||
<div class="ukefu-empty" style="background: none">
|
||||
<i class="layui-icon"></i>
|
||||
<div style="">未触发知识库查询</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</#if>
|
||||
<div class="layui-tab-item">
|
||||
<div class="box">
|
||||
<div class="box-title">
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
var test = window.location.search;
|
||||
if(isAisuggest && isAisuggest == "true"){
|
||||
switchQuickReply();
|
||||
}
|
||||
})
|
||||
document.getElementById('chat_msg_list').scrollTop = document.getElementById('chat_msg_list').scrollHeight;
|
||||
layui.use('element', function(){
|
||||
@ -478,12 +570,78 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
|
||||
var count = editor.count("text");
|
||||
if(count>0){
|
||||
var message = document.getElementById('message').value;
|
||||
top.WebIM.sendMessage(message , '${user.id!''}' , "${curagentuser.appid!''}" , "${user.sessionid!''}" , "${orgi!''}" , "<#if curagentuser??>${curagentuser.userid!''}</#if>" , "${user.username!''}");
|
||||
top.WebIM.sendMessage(message , "${user.id!''}" , "${curagentuser.appid!''}" , "${user.sessionid!''}" , "${orgi!''}" , "<#if curagentuser??>${curagentuser.userid!''}</#if>" , "${user.username!''}");
|
||||
}
|
||||
editor.html('');
|
||||
showOrHide('none');
|
||||
};
|
||||
|
||||
$(document).keyup(function(event){
|
||||
function chooseAnswer(data){
|
||||
editor.html(data)
|
||||
}
|
||||
|
||||
function showOrHide(data){
|
||||
$("#agentAnswer").css("display",data)
|
||||
}
|
||||
|
||||
// 排序
|
||||
function sortByKey(array, key) {
|
||||
return array.sort(function(a, b) {
|
||||
var x = a[key]; var y = b[key];
|
||||
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
|
||||
});
|
||||
}
|
||||
|
||||
function switchQuickReply(){
|
||||
var hatContentHtml = $("#chat_msg_list .chat-block").last().find(".chatting-left .chat-content").html();
|
||||
if($.trim(hatContentHtml)){
|
||||
restApiRequest({
|
||||
silent: true,
|
||||
path: 'chatbot',
|
||||
data: {
|
||||
ops: 'faq',
|
||||
snsaccountid: "<#if curagentuser??>${curagentuser.appid!''}</#if>",
|
||||
userId:"<#if curagentuser??>${curagentuser.userid!''}</#if>",
|
||||
textMessage:hatContentHtml
|
||||
}
|
||||
}).then(function(result){
|
||||
if(result.rc === 0){
|
||||
if(result.data.length>0){
|
||||
$("#quickReplyBox").html("");
|
||||
$.each(sortByKey(result.data,'score'),function(i,n){
|
||||
var li = ' <li class="ukefu-agentservice-list" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">\n' +
|
||||
' <div class="nowrap" title="'+result.data[i].post+'">问题:'+result.data[i].post+'</div>\n' +
|
||||
' <div style="color: #333">\n' +
|
||||
' <p class="nowrap" title="'+result.data[i].reply_plain_text+'" style="float: left ">答案:'+result.data[i].reply_plain_text+'</p>\n' +
|
||||
' <button style="float: right" class="layui-btn layui-btn-mini" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">选择</button>\n' +
|
||||
' </div>\n' +
|
||||
' </li>'
|
||||
$("#quickReplyBox").append(li);
|
||||
if (i>4){
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if(!$("#robot").hasClass('layui-this')){
|
||||
$("#dot").css("display","inline-block")
|
||||
}
|
||||
}else{
|
||||
$("#dot").css("display","none")
|
||||
$("#quickReplyBox").html(' <li style="list-style: none;background-image: url();padding: 50px 0 50px;">\n' +
|
||||
' <div class="ukefu-empty" style="background: none">\n' +
|
||||
' <i class="layui-icon"></i>\n' +
|
||||
' <div style="">在知识库中未得到相关问题</div>\n' +
|
||||
' </div>\n' +
|
||||
' </li>');
|
||||
}
|
||||
}
|
||||
}, function(error){
|
||||
console.log("error", error);
|
||||
// 服务器异常
|
||||
top.layer.msg('服务器抽风,请稍后再试!',{icon: 2, time: 3000})
|
||||
})
|
||||
}
|
||||
}
|
||||
$("#searchconter").keyup(function(event){
|
||||
if(event.keyCode ==13){
|
||||
$("#search").click();
|
||||
}
|
||||
@ -590,7 +748,6 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
|
||||
,done: function(page, next){ //执行下一页的回调
|
||||
//模拟数据插入
|
||||
current += 20;
|
||||
console.log(current);
|
||||
setTimeout(function(){
|
||||
var lis = [];
|
||||
var pages = 0;
|
||||
|
@ -17,7 +17,7 @@
|
||||
<select id="agent" name="agentno" class="ukefu-input" lay-ignore style="width: 100px;display: inline-block">
|
||||
<option value="">请选择技能组</option>
|
||||
</select>
|
||||
<div class="layui-input-inline" style="float: right;width: auto">
|
||||
<div class="layui-input-inline" style="float: right;width: auto;margin-right: 0px">
|
||||
<button class="layui-btn layui-btn-small layui-btn-primary" style="color:#ffffff;">
|
||||
<i class="layui-icon"></i>
|
||||
</button>
|
||||
|
@ -1,5 +1,7 @@
|
||||
<link rel="stylesheet" href="/js/ztree/zTreeStyle/zTreeStyle.css">
|
||||
<script src="/js/ztree/jquery.ztree.all.min.js"></script>
|
||||
<script src="/js/lodash-4.17.4.min.js"></script>
|
||||
<script src="/js/CSKeFu_Rest_Request.v1.js"></script>
|
||||
<!--<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>-->
|
||||
<script id="message_tpl" type="text/html">
|
||||
<div class="clearfix chat-block" <%if(data.type == 'writing'){%>id="writing"<%}%>>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script language="javascript">
|
||||
cursession = "<#if curagentuser??>${curagentuser.userid!''}</#if>";
|
||||
var userid = "${curagentuser.userid!''}", agentserviceid = "${curagentuser.agentserviceid!''}", agentuserid = "${curagentuser.id}";
|
||||
var userid = "${curagentuser.userid!''}", agentserviceid = "${curagentuser.agentserviceid!''}", agentuserid = "${curagentuser.id}" ,isCcaAisuggest = "${ccaAisuggest}";
|
||||
</script>
|
||||
|
||||
<div class="main-agentuser">
|
||||
@ -56,6 +56,15 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-bottom">
|
||||
<div id="ccaAgentAnswer" style="width: 50%;min-width:310px;height: 180px;border: 1px solid #eee;position: absolute;top: -180px;right:0px;background: #ffffff;display: none">
|
||||
<h1 class="site-h1" style="background-color:#EEEEEE;padding: 0px 10px" >知识库联想
|
||||
<i class="layui-icon" style="position: absolute;top: 0px;right: 5px;font-size:16px;z-index: 10" onclick="showOrHide('none')">ဆ</i>
|
||||
</h1>
|
||||
<div style="width: calc(100% - 19px);height: 129px;position: absolute;top: 31px;overflow-y: scroll;padding: 10px 10px">
|
||||
<ul class="info-list ukefu-quick-reply" style="width: 100%;height: auto" id="ccaQuickReplyAgentBox">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<textarea id="message" name="message"></textarea>
|
||||
@ -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!''}</#if>",
|
||||
userId:"<#if curagentuser??>${curagentuser.userid!''}</#if>",
|
||||
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 = ' <li class="ukefu-agentservice-list" style="font-size: 14px;line-height:22px" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">\n' +
|
||||
' <div class="nowrap" title="'+result.data[i].post+'">问题:'+result.data[i].post+'</div>\n' +
|
||||
' <div style="color: #333">\n' +
|
||||
' <p title="'+result.data[i].reply_plain_text+'" class="nowrap" style="float: left ">答案:'+result.data[i].reply_plain_text+'</p>\n' +
|
||||
' <button style="float: right" class="layui-btn layui-btn-mini" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">选择</button>\n' +
|
||||
' </div>\n' +
|
||||
' </li>'
|
||||
$("#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})
|
||||
})
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
@ -154,6 +210,12 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
|
||||
<div class="layui-tab" style="margin-top:0px;">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">访客</li>
|
||||
<#if ccaAisuggest?? && ccaAisuggest == true>
|
||||
<li id="robot" onclick="$('#dot').css('display','none')">
|
||||
<span>智能机器人</span>
|
||||
<span id="dot" style=" width: 7px;height: 7px;background: red;-moz-border-radius: 50%;-webkit-border-radius: 50%;border-radius: 50%;position: absolute;top: 5px;display: none"></span>
|
||||
</li>
|
||||
</#if>
|
||||
<li>历史</li>
|
||||
<li>搜索历史消息</li>
|
||||
<#if models?seq_contains("workorders")>
|
||||
@ -264,6 +326,28 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
|
||||
</#if>
|
||||
</div>
|
||||
|
||||
<#if ccaAisuggest?? && ccaAisuggest == true>
|
||||
<div class="layui-tab-item">
|
||||
<div class="box">
|
||||
<div class="box-title">
|
||||
<h1 class="site-h1" style="background-color:#EEEEEE;">
|
||||
知识库快捷
|
||||
</h1>
|
||||
</div>
|
||||
<div class="box-body" style="padding:0px 10px;">
|
||||
<ul class="info-list ukefu-quick-reply" id="ccaQuickReplyBox">
|
||||
<li style="list-style: none;background-image: url();padding: 50px 0 50px;">
|
||||
<div class="ukefu-empty" style="background: none">
|
||||
<i class="layui-icon"></i>
|
||||
<div style="">未触发知识库查询</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</#if>
|
||||
|
||||
<div class="layui-tab-item">
|
||||
<div class="box">
|
||||
<div class="box-title">
|
||||
@ -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);
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
var test = window.location.search;
|
||||
if(isCcaAisuggest && isCcaAisuggest == "true"){
|
||||
switchQuickReply();
|
||||
}
|
||||
})
|
||||
document.getElementById('chat_msg_list_cca').scrollTop = document.getElementById('chat_msg_list_cca').scrollHeight;
|
||||
layui.use('element', function(){
|
||||
@ -486,9 +577,76 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
|
||||
top.WebIM.sendIntervention("${user.id!''}","${curagentuser.id!''}", "${user.sessionid!''}", "text", message);
|
||||
}
|
||||
editor.html('');
|
||||
showOrHide('none');
|
||||
};
|
||||
|
||||
$(document).keyup(function(event){
|
||||
function chooseAnswer(data){
|
||||
editor.html(data)
|
||||
}
|
||||
|
||||
function showOrHide(data){
|
||||
$("#ccaAgentAnswer").css("display",data)
|
||||
}
|
||||
|
||||
// 排序
|
||||
function sortByKey(array, key) {
|
||||
return array.sort(function(a, b) {
|
||||
var x = a[key]; var y = b[key];
|
||||
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
|
||||
});
|
||||
}
|
||||
|
||||
function switchQuickReply(){
|
||||
var hatContentHtml = $("#chat_msg_list_cca .chat-block").last().find(".chatting-left .chat-content").html();
|
||||
if($.trim(hatContentHtml)){
|
||||
restApiRequest({
|
||||
silent: true,
|
||||
path: 'chatbot',
|
||||
data: {
|
||||
ops: 'faq',
|
||||
snsaccountid: "<#if curagentuser??>${curagentuser.appid!''}</#if>",
|
||||
userId:"<#if curagentuser??>${curagentuser.userid!''}</#if>",
|
||||
textMessage:hatContentHtml
|
||||
}
|
||||
}).then(function(result){
|
||||
if(result.rc === 0){
|
||||
if(result.data.length>0){
|
||||
$("#ccaQuickReplyBox").html("");
|
||||
$.each(sortByKey(result.data,'score'),function(i,n){
|
||||
var li = ' <li class="ukefu-agentservice-list" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">\n' +
|
||||
' <div class="nowrap" title="'+result.data[i].post+'">问题:'+result.data[i].post+'</div>\n' +
|
||||
' <div style="color: #333">\n' +
|
||||
' <p class="nowrap" title="'+result.data[i].reply_plain_text+'" style="float: left ">答案:'+result.data[i].reply_plain_text+'</p>\n' +
|
||||
' <button style="float: right" class="layui-btn layui-btn-mini" onclick="chooseAnswer(\''+result.data[i].reply_plain_text+'\')">选择</button>\n' +
|
||||
' </div>\n' +
|
||||
' </li>'
|
||||
$("#ccaQuickReplyBox").append(li);
|
||||
if (i>4){
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if(!$("#robot").hasClass('layui-this')){
|
||||
$("#dot").css("display","inline-block")
|
||||
}
|
||||
}else{
|
||||
$("#dot").css("display","none")
|
||||
$("#ccaQuickReplyBox").html(' <li style="list-style: none;background-image: url();padding: 50px 0 50px;">\n' +
|
||||
' <div class="ukefu-empty" style="background: none">\n' +
|
||||
' <i class="layui-icon"></i>\n' +
|
||||
' <div style="">在知识库中未得到相关问题</div>\n' +
|
||||
' </div>\n' +
|
||||
' </li>');
|
||||
}
|
||||
}
|
||||
}, function(error){
|
||||
console.log("error", error);
|
||||
// 服务器异常
|
||||
top.layer.msg('服务器抽风,请稍后再试!',{icon: 2, time: 3000})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
$("#searchconter").keyup(function(event){
|
||||
if(event.keyCode ==13){
|
||||
$("#search").click();
|
||||
}
|
||||
@ -595,7 +753,6 @@ word-break: break-all;"><#if curagentuser??>${curagentuser.username!''}<#if cura
|
||||
,done: function(page, next){ //执行下一页的回调
|
||||
//模拟数据插入
|
||||
current += 20;
|
||||
console.log(current);
|
||||
setTimeout(function(){
|
||||
var lis = [];
|
||||
var pages = 0;
|
||||
|
@ -21,10 +21,10 @@
|
||||
<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;">
|
||||
</div>
|
||||
<div class="ukef-leavemsg-tip">
|
||||
<div class="ukef-leavemsg-tip" style="width: 100%;max-width: 550px">
|
||||
<#if inviteData?? && inviteData.consult_info_message??>${(inviteData.consult_info_message!'')?no_esc}</#if>
|
||||
</div>
|
||||
<div class="leaveCon">
|
||||
<div class="leaveCon" style="width: 100%;max-width: 550px">
|
||||
<form action="" method="" name="">
|
||||
<#if inviteData?? && inviteData.consult_info_name == true>
|
||||
<div class="layui-form-item ukefu-form-item">
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
<script type="text/javascript" src="/js/jquery-1.10.2.min.js"></script>
|
||||
<script src="/js/jquery.form.js"></script>
|
||||
|
||||
<script type="text/javascript" src="/im/js/kindeditor/kindeditor.js"></script>
|
||||
<script type="text/javascript" src="/im/js/kindeditor/lang/zh-CN.js"></script>
|
||||
<style>
|
||||
@ -168,8 +167,8 @@
|
||||
});
|
||||
</script>
|
||||
<!-- kindeditor -->
|
||||
</head>
|
||||
<body class="ukefu-im-theme" style="overflow:hidden;height:calc(100%);overflow-y: atuo;/* 或者scroll */-webkit-overflow-scrolling: touch;/* 解决ios滑动不流畅问题 */" class="ukefu-point-text">
|
||||
</head> n
|
||||
<body class="ukefu-im-theme ukefu-point-text" style="overflow:hidden;height:100%;max-height:100%;position: fixed;/* 或者scroll */-webkit-overflow-scrolling: touch;/* 解决ios滑动不流畅问题 */">
|
||||
<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>"
|
||||
|
@ -454,9 +454,9 @@ function openAgentChatDialog(url){
|
||||
}
|
||||
|
||||
<#if webimexist == true >
|
||||
Fingerprint2.get({}, function(components){
|
||||
Fingerprint2.get({extraComponents: [<#if channelVisitorSeparate?? && channelVisitorSeparate == true>{key: "cskefuAppId", getData: function(done, options){done("${appid!''}")}}</#if>]}, function(components){
|
||||
var glue = components.map(function (component) { return component.value })
|
||||
cskefuOnlineUserId = Fingerprint2.x64hash128(glue.join(''), 31)
|
||||
cskefuOnlineUserId = Fingerprint2.x64hash128(glue.join(''), 31);
|
||||
cskefu.ajax(cskefu.in+"&userid="+cskefuOnlineUserId+"&t="+new Date().getTime() , function(data){
|
||||
if(data == "in"){}else{
|
||||
cskefu.display();
|
||||
|
@ -33,7 +33,7 @@ var ukefu = {
|
||||
window.location.replace(url+"&t="+new Date().getTime());
|
||||
}
|
||||
}
|
||||
Fingerprint2.get({}, function(components){
|
||||
Fingerprint2.get({extraComponents: [<#if channelVisitorSeparate?? && channelVisitorSeparate == true>{key: "cskefuAppId", getData: function(done, options){done("${appid!''}")}}</#if>]}, function(components){
|
||||
var glue = components.map(function (component) { return component.value })
|
||||
cskefuOnlineUserId = Fingerprint2.x64hash128(glue.join(''), 31)
|
||||
ukefu.chat = ukefu.chat + "<#if userid??>&userid=${userid}<#else>&userid="+cskefuOnlineUserId+"</#if>&sessionid=${sessionid!''}<#if ai??>&ai=${ai}</#if><#if title??>&title=${title?url}</#if><#if traceid??>&url=${url?url}</#if><#if traceid??>&traceid=${traceid}</#if>";
|
||||
|
@ -2829,10 +2829,10 @@ select{
|
||||
display:none;
|
||||
}
|
||||
.chatting-right div.chat-content img{
|
||||
max-width:460px;
|
||||
max-width:100%;
|
||||
}
|
||||
.chatting-left div.chat-content img{
|
||||
max-width:460px;
|
||||
max-width:100%;
|
||||
}
|
||||
.layui-layout-content .layui-nav-child dd a{
|
||||
font-size:13px !important;
|
||||
|
@ -1538,6 +1538,7 @@ CREATE TABLE `uk_consult_invite` (
|
||||
`agentctrlenter` tinyint(4) DEFAULT '0' COMMENT '启用坐席端CTRL+Enter发送消息',
|
||||
`ctrlenter` tinyint(4) DEFAULT '0' COMMENT '启用访客端CTRL+Enter发送消息',
|
||||
`whitelist_mode` tinyint(4) DEFAULT '0' COMMENT '启用白名单',
|
||||
`aisuggest` tinyint(4) DEFAULT '0' COMMENT '启用智能建议',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT COMMENT='访客网站配置表';
|
||||
|
||||
@ -3414,6 +3415,7 @@ CREATE TABLE `cs_chatbot` (
|
||||
`sns_account_identifier` varchar(100) NOT NULL COMMENT '渠道标识',
|
||||
`enabled` tinyint(1) DEFAULT '0' COMMENT '是否开启',
|
||||
`workmode` varchar(32) NOT NULL COMMENT '工作模式',
|
||||
`aisuggest` tinyint(1) DEFAULT '0' COMMENT '启用智能建议',
|
||||
PRIMARY KEY (`ID`) USING BTREE,
|
||||
UNIQUE KEY `snsid` (`sns_account_identifier`,`orgi`) USING BTREE COMMENT '按照渠道标识唯一'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT COMMENT='机器人客服表';
|
||||
|
@ -0,0 +1,35 @@
|
||||
USE `cosinee`;
|
||||
-- -----------------
|
||||
-- prepare variables
|
||||
-- -----------------
|
||||
|
||||
|
||||
|
||||
SET @dbname = DATABASE ( );
|
||||
SET @tablename = "cs_chatbot";
|
||||
SET @columnname = "aisuggest";
|
||||
|
||||
SET @preparedStatement = (
|
||||
SELECT
|
||||
IF
|
||||
(
|
||||
(
|
||||
SELECT
|
||||
COUNT( * )
|
||||
FROM
|
||||
INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE
|
||||
( table_name = @tablename )
|
||||
AND ( table_schema = @dbname )
|
||||
AND ( column_name = @columnname )
|
||||
) > 0,
|
||||
"SELECT 1",
|
||||
CONCAT( "ALTER TABLE ", @tablename, " ADD ", @columnname, " tinyint(1) DEFAULT '0' COMMENT '启用智能建议';" )
|
||||
)
|
||||
);
|
||||
|
||||
PREPARE alterIfNotExists
|
||||
FROM
|
||||
@preparedStatement;
|
||||
EXECUTE alterIfNotExists;
|
||||
DEALLOCATE PREPARE alterIfNotExists;
|
@ -0,0 +1,35 @@
|
||||
USE `cosinee`;
|
||||
-- -----------------
|
||||
-- prepare variables
|
||||
-- -----------------
|
||||
|
||||
|
||||
|
||||
SET @dbname = DATABASE ( );
|
||||
SET @tablename = "uk_consult_invite";
|
||||
SET @columnname = "aisuggest";
|
||||
|
||||
SET @preparedStatement = (
|
||||
SELECT
|
||||
IF
|
||||
(
|
||||
(
|
||||
SELECT
|
||||
COUNT( * )
|
||||
FROM
|
||||
INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE
|
||||
( table_name = @tablename )
|
||||
AND ( table_schema = @dbname )
|
||||
AND ( column_name = @columnname )
|
||||
) > 0,
|
||||
"SELECT 1",
|
||||
CONCAT( "ALTER TABLE ", @tablename, " ADD ", @columnname, " TINYINT(4) DEFAULT '0' COMMENT '启用智能建议';" )
|
||||
)
|
||||
);
|
||||
|
||||
PREPARE alterIfNotExists
|
||||
FROM
|
||||
@preparedStatement;
|
||||
EXECUTE alterIfNotExists;
|
||||
DEALLOCATE PREPARE alterIfNotExists;
|
@ -48,8 +48,9 @@ services:
|
||||
- CSKEFU_MODULE_CONTACTS=true
|
||||
- CSKEFU_MODULE_CHATBOT=true
|
||||
- SKYPE_CHANNEL_CRM=${SKYPE_CHANNEL_CRM:-placeholder}
|
||||
- BOT_THRESHOLD_FAQ_BEST_REPLY=${BOT_THRESHOLD_FAQ_BEST_REPLY:-0.8}
|
||||
- BOT_THRESHOLD_FAQ_SUGG_REPLY=${BOT_THRESHOLD_FAQ_SUGG_REPLY:-0.6}
|
||||
- BOT_THRESHOLD_FAQ_BEST_REPLY=${BOT_THRESHOLD_FAQ_BEST_REPLY:-0.9}
|
||||
- BOT_THRESHOLD_FAQ_SUGG_REPLY=${BOT_THRESHOLD_FAQ_SUGG_REPLY:-0.3}
|
||||
- CSKEFU_SETTINGS_WEBIM_VISITOR_SEPARATE=false
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
|
@ -32,6 +32,7 @@ import com.chatopera.cc.proxy.OnlineUserProxy;
|
||||
import com.chatopera.cc.util.Menu;
|
||||
import com.chatopera.cc.util.SystemEnvHelper;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
@ -124,9 +125,18 @@ public class ApiChatbotController extends Handler {
|
||||
case "disable":
|
||||
json = enable(j, false);
|
||||
break;
|
||||
case "enableaisuggest":
|
||||
json = enableAiSuggest(j, true);
|
||||
break;
|
||||
case "disableaisuggest":
|
||||
json = enableAiSuggest(j, false);
|
||||
break;
|
||||
case "vacant":
|
||||
json = vacant(j, orgi, logined.isAdmin());
|
||||
break;
|
||||
case "faq":
|
||||
json = faq(j, orgi);
|
||||
break;
|
||||
default:
|
||||
json.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_2);
|
||||
json.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的操作。");
|
||||
@ -222,6 +232,44 @@ public class ApiChatbotController extends Handler {
|
||||
return resp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable Chatbot 智能回复
|
||||
*
|
||||
* @param j
|
||||
* @return
|
||||
*/
|
||||
private JsonObject enableAiSuggest(JsonObject j, boolean isEnabled) {
|
||||
JsonObject resp = new JsonObject();
|
||||
if ((!j.has("id")) || StringUtils.isBlank(j.get("id").getAsString())) {
|
||||
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
|
||||
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的操作,id不能为空。");
|
||||
return resp;
|
||||
}
|
||||
|
||||
final String id = j.get("id").getAsString();
|
||||
Chatbot c = chatbotRes.findOne(id);
|
||||
|
||||
if (c == null) {
|
||||
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_4);
|
||||
resp.addProperty(RestUtils.RESP_KEY_ERROR, "该聊天机器人不存在。");
|
||||
return resp;
|
||||
}
|
||||
|
||||
c.setAisuggest(isEnabled);
|
||||
chatbotRes.save(c);
|
||||
|
||||
// 更新访客网站配置
|
||||
CousultInvite invite = OnlineUserProxy.consult(c.getSnsAccountIdentifier(), c.getOrgi());
|
||||
invite.setAisuggest(isEnabled);
|
||||
consultInviteRes.save(invite);
|
||||
OnlineUserProxy.cacheConsult(invite);
|
||||
|
||||
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_SUCC);
|
||||
resp.addProperty(RestUtils.RESP_KEY_DATA, "完成。");
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新聊天机器人
|
||||
*
|
||||
@ -417,6 +465,7 @@ public class ApiChatbotController extends Handler {
|
||||
invite.setAisuccesstip(null);
|
||||
invite.setAifirst(false);
|
||||
invite.setAiid(null);
|
||||
invite.setAisuggest(false);
|
||||
consultInviteRes.save(invite);
|
||||
OnlineUserProxy.cacheConsult(invite);
|
||||
}
|
||||
@ -558,4 +607,57 @@ public class ApiChatbotController extends Handler {
|
||||
return resp;
|
||||
}
|
||||
}
|
||||
|
||||
private JsonObject faq(final JsonObject j, String orgi) {
|
||||
JsonObject resp = new JsonObject();
|
||||
if ((!j.has("snsaccountid")) || StringUtils.isBlank(j.get("snsaccountid").getAsString())) {
|
||||
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
|
||||
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的操作,snsaccountid不能为空。");
|
||||
return resp;
|
||||
}
|
||||
|
||||
final String snsaccountid = j.get("snsaccountid").getAsString();
|
||||
Chatbot c = chatbotRes.findBySnsAccountIdentifierAndOrgi(snsaccountid, orgi);
|
||||
|
||||
if (c == null) {
|
||||
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_4);
|
||||
resp.addProperty(RestUtils.RESP_KEY_ERROR, "该聊天机器人不存在。");
|
||||
return resp;
|
||||
}
|
||||
|
||||
String userId = j.get("userId").getAsString();
|
||||
String textMessage = j.get("textMessage").getAsString();
|
||||
|
||||
try {
|
||||
com.chatopera.bot.sdk.Chatbot bot = new com.chatopera.bot.sdk.Chatbot(
|
||||
c.getClientId(), c.getSecret(), botServiecProvider);
|
||||
|
||||
JSONObject result = bot.faq(
|
||||
userId,
|
||||
textMessage,
|
||||
Double.parseDouble(SystemEnvHelper.getenv(ChatbotConstants.THRESHOLD_FAQ_BEST_REPLY, "0.8")),
|
||||
Double.parseDouble(SystemEnvHelper.getenv(ChatbotConstants.THRESHOLD_FAQ_SUGG_REPLY, "0.6"))
|
||||
);
|
||||
if (result.getInt("rc") == 0) {
|
||||
JsonParser jsonParser = new JsonParser();
|
||||
JsonElement data = jsonParser.parse(result.getJSONArray("data").toString());
|
||||
|
||||
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_SUCC);
|
||||
resp.add(RestUtils.RESP_KEY_DATA, data);
|
||||
} else {
|
||||
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_5);
|
||||
resp.addProperty(RestUtils.RESP_KEY_DATA, "查询不成功,智能问答引擎服务异常。");
|
||||
}
|
||||
} catch (
|
||||
MalformedURLException e) {
|
||||
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_6);
|
||||
resp.addProperty(RestUtils.RESP_KEY_DATA, "查询不成功,智能问答引擎地址不合法。");
|
||||
} catch (
|
||||
ChatbotException e) {
|
||||
|
||||
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_5);
|
||||
resp.addProperty(RestUtils.RESP_KEY_DATA, "查询不成功,智能问答引擎服务异常。");
|
||||
}
|
||||
return resp;
|
||||
}
|
||||
}
|
||||
|
@ -51,8 +51,8 @@ public class PluginDescriptor implements IPluginDescriptor {
|
||||
public Map<String, String> getEnvironmentVariables() {
|
||||
Map<String, String> env = new HashMap<>();
|
||||
env.put(ChatbotConstants.BOT_PROVIDER, "https://bot.chatopera.com");
|
||||
env.put(ChatbotConstants.THRESHOLD_FAQ_BEST_REPLY, "0.8");
|
||||
env.put(ChatbotConstants.THRESHOLD_FAQ_SUGG_REPLY, "0.6");
|
||||
env.put(ChatbotConstants.THRESHOLD_FAQ_BEST_REPLY, "0.9");
|
||||
env.put(ChatbotConstants.THRESHOLD_FAQ_SUGG_REPLY, "0.3");
|
||||
return env;
|
||||
}
|
||||
}
|
@ -54,17 +54,29 @@
|
||||
<div class="row" style="padding:5px;">
|
||||
<div class="col-lg-12">
|
||||
<fieldset class="layui-elem-field layui-field-title">
|
||||
<legend>工作状态</legend>
|
||||
<legend>智能客服</legend>
|
||||
<div class="layui-field-box">
|
||||
<blockquote class="layui-elem-quote layui-quote-nm">
|
||||
<p>在开启状态下,在访客端可以看到【智能坐席】对话窗口并与机器人客服对话。</p>
|
||||
<p>在开启状态下,在访客端可以看到<b>智能客服</b>对话窗口并与机器人客服对话。</p>
|
||||
</blockquote>
|
||||
<form class="layui-form" action="">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<input type="checkbox" lay-filter="bot-workstatus" name="switch" lay-skin="switch" lay-text="启用|禁用" <#if currentbot.enabled>checked</#if>>
|
||||
</div>
|
||||
<!-- <div class="layui-form-mid layui-word-aux">在开启状态下,在访客端可以看到【智能坐席】对话窗口并与机器人客服对话。</div>-->
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<legend>知识库建议</legend>
|
||||
<div class="layui-field-box">
|
||||
<blockquote class="layui-elem-quote layui-quote-nm">
|
||||
<p>知识库建议包括<b>知识库联想</b>和<b>知识库快捷</b>。<b>知识库联想</b>:当坐席与访客进行对话过程中,坐席输入消息时是否得到机器人的建议回复;<b>知识库快捷</b>:当坐席与访客进行对话过程中,坐席收到访客的消息时是否得到机器人的建议回复。</p>
|
||||
</blockquote>
|
||||
<form class="layui-form" action="">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<input type="checkbox" lay-filter="bot-aisuggest" name="bot-aisuggest" lay-skin="switch" lay-text="启用|禁用" <#if currentbot.aisuggest>checked</#if>>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@ -269,6 +281,7 @@
|
||||
function setChatbotWorkstatus(id, workstatus){
|
||||
restApiRequest({
|
||||
path: "chatbot",
|
||||
silent: true,
|
||||
data: {
|
||||
ops: workstatus?"enable":"disable",
|
||||
id: id
|
||||
@ -276,6 +289,17 @@
|
||||
});
|
||||
}
|
||||
|
||||
function setChatbotAiSuggest(id, aisuggest){
|
||||
restApiRequest({
|
||||
path: "chatbot",
|
||||
silent: true,
|
||||
data: {
|
||||
ops: aisuggest?"enableAiSuggest":"disableAiSuggest",
|
||||
id: id
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
layui.use(['form'], function(){
|
||||
var form = layui.form();
|
||||
form.render();
|
||||
@ -283,5 +307,9 @@
|
||||
form.on('switch(bot-workstatus)', function (data) {
|
||||
setChatbotWorkstatus('${currentbotid}', data.elem.checked);
|
||||
});
|
||||
|
||||
form.on('switch(bot-aisuggest)', function (data) {
|
||||
setChatbotAiSuggest('${currentbotid}', data.elem.checked);
|
||||
});
|
||||
});
|
||||
</script>
|
Loading…
x
Reference in New Issue
Block a user