提交 0a073e9e 编写于 作者: Y Yu

close #442 optimize the ACD

上级 799add4f
......@@ -22,9 +22,11 @@ import com.chatopera.cc.basic.MainUtils;
import com.chatopera.cc.cache.Cache;
import com.chatopera.cc.model.AgentStatus;
import com.chatopera.cc.model.AgentUser;
import com.chatopera.cc.model.SNSAccount;
import com.chatopera.cc.model.SessionConfig;
import com.chatopera.cc.persistence.repository.AgentUserRepository;
import com.chatopera.cc.persistence.repository.OnlineUserRepository;
import com.chatopera.cc.persistence.repository.SNSAccountRepository;
import com.chatopera.cc.persistence.repository.SessionConfigRepository;
import com.chatopera.cc.util.HashMapUtils;
import com.chatopera.cc.util.WebIMReport;
......@@ -58,6 +60,9 @@ public class ACDPolicyService {
@Autowired
private AgentUserRepository agentUserRes;
@Autowired
private SNSAccountRepository snsAccountRes;
/**
* 载入坐席 ACD策略配置
*
......@@ -229,25 +234,28 @@ public class ACDPolicyService {
*
* TODO 指定技能组无用户,停止分配
*/
SNSAccount snsAccount = snsAccountRes.findBySnsidAndOrgi(agentUser.getAppid(), orgi);
// 对于该租户的所有客服
// for (final Map.Entry<String, AgentStatus> entry : map.entrySet()) {
// if ((!entry.getValue().isBusy()) && (entry.getValue().getUsers() < sessionConfig.getMaxuser())) {
// agentStatuses.add(entry.getValue());
// logger.info(
// "[filterOutAvailableAgentStatus] <Redundance> find ready agent {}, agentname {}, status {}, service {}/{}, skills {}",
// entry.getValue().getAgentno(), entry.getValue().getUsername(), entry.getValue().getStatus(),
// entry.getValue().getUsers(),
// entry.getValue().getMaxusers(),
// HashMapUtils.concatKeys(entry.getValue().getSkills(), "|"));
// } else {
// logger.info(
// "[filterOutAvailableAgentStatus] <Redundance> skip ready agent {}, name {}, status {}, service {}/{}, skills {}",
// entry.getValue().getAgentno(), entry.getValue().getUsername(), entry.getValue().getStatus(),
// entry.getValue().getUsers(),
// entry.getValue().getMaxusers(),
// HashMapUtils.concatKeys(entry.getValue().getSkills(), "|"));
// }
// }
for (final Map.Entry<String, AgentStatus> entry : map.entrySet()) {
if ((!entry.getValue().isBusy()) && (entry.getValue().getUsers() < sessionConfig.getMaxuser()) && entry.getValue().getSkills().containsKey(snsAccount.getOrgan())) {
agentStatuses.add(entry.getValue());
logger.info(
"[filterOutAvailableAgentStatus] <Redundance> find ready agent {}, agentname {}, status {}, service {}/{}, skills {}",
entry.getValue().getAgentno(), entry.getValue().getUsername(), entry.getValue().getStatus(),
entry.getValue().getUsers(),
entry.getValue().getMaxusers(),
HashMapUtils.concatKeys(entry.getValue().getSkills(), "|"));
} else {
logger.info(
"[filterOutAvailableAgentStatus] <Redundance> skip ready agent {}, name {}, status {}, service {}/{}, skills {}",
entry.getValue().getAgentno(), entry.getValue().getUsername(), entry.getValue().getStatus(),
entry.getValue().getUsers(),
entry.getValue().getMaxusers(),
HashMapUtils.concatKeys(entry.getValue().getSkills(), "|"));
}
}
}
logger.info("[filterOutAvailableAgentStatus] agent status list size: {}", agentStatuses.size());
......
......@@ -19,6 +19,7 @@ package com.chatopera.cc.acd.middleware.visitor;
import com.chatopera.cc.acd.ACDPolicyService;
import com.chatopera.cc.acd.ACDWorkMonitor;
import com.chatopera.cc.acd.basic.ACDComposeContext;
import com.chatopera.cc.basic.MainContext;
import com.chatopera.cc.basic.MainUtils;
import com.chatopera.cc.model.AgentReport;
import com.chatopera.cc.model.SessionConfig;
......@@ -66,8 +67,12 @@ public class ACDVisSessionCfgMw implements Middleware<ACDComposeContext> {
ctx.setMessage(sessionConfig.getNotinwhmsg());
} else if (report.getAgents() == 0) {
// 没有就绪的坐席
logger.info("[apply] find no agents, redirect to leave a message.");
ctx.setNoagent(true);
if (ctx.getChannel().equals(MainContext.ChannelType.MESSENGER.toString())) {
next.apply();
} else {
logger.info("[apply] find no agents, redirect to leave a message.");
ctx.setNoagent(true);
}
} else {
logger.info("[apply] find agents size {}, allocate agent in next.", report.getAgents());
// 具备工作中的就绪坐席,进入筛选坐席
......
......@@ -48,6 +48,7 @@ import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
......@@ -107,6 +108,7 @@ public class Handler {
/**
* 获得登录账号的当前导航的组织机构
*
* @param request
* @return
*/
......@@ -122,7 +124,19 @@ public class Handler {
Organ organ = (Organ) request.getSession(true).getAttribute(Constants.ORGAN_SESSION_NAME);
if (organ == null) {
if (organs.size() > 0) {
organ = organs.get(0);
ArrayList<String> organTree = new ArrayList();
organs.stream().forEach(o -> {
if (organTree.stream().filter(p -> StringUtils.equals(o.getParent(), p)).findFirst().isPresent()) {
int index = organTree.indexOf(o.getParent());
organTree.add(index + 1, o.getId());
} else {
organTree.add(0, o.getId());
}
});
organ = organs.stream().filter(o ->
StringUtils.equals(o.getId(), organTree.get(0))
).findFirst().orElse(organs.get(0));
request.getSession(true).setAttribute(Constants.ORGAN_SESSION_NAME, organ);
}
}
......
......@@ -166,7 +166,7 @@ public class AgentAuditController extends Handler {
if (StringUtils.isBlank(skill) && StringUtils.isBlank(agentno)) {
if (organs.size() > 0) {
agentUsers = agentUserRes.findByOrgiAndStatusAndSkillInAndAgentnoIsNot(
agentUsers = agentUserRes.findByOrgiAndStatusAndSkillInAndAgentnoIsNotAndChatbotopsIsFalse(
orgi, MainContext.AgentUserStatusEnum.INSERVICE.toString(), organs.keySet(), logined.getId(), defaultSort);
}
} else if (StringUtils.isNotBlank(skill) && StringUtils.isNotBlank(agentno)) {
......
......@@ -40,6 +40,7 @@ public class FbOTN implements Serializable {
private Date createtime;
private Date updatetime;
private Date sendtime;
private Integer melinkNum;
private Integer subNum;
private FbMessenger fbMessenger;
......@@ -152,6 +153,14 @@ public class FbOTN implements Serializable {
this.subNum = subNum;
}
public Integer getMelinkNum() {
return melinkNum;
}
public void setMelinkNum(Integer melinkNum) {
this.melinkNum = melinkNum;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "pageId", referencedColumnName = "pageId", insertable = false, updatable = false)
@NotFound(action = NotFoundAction.IGNORE)
......
......@@ -62,7 +62,7 @@ public interface AgentUserRepository extends JpaRepository<AgentUser, String> {
List<AgentUser> findByOrgiAndStatusAndSkillAndAgentnoIsNot(final String orgi, final String status, final String skill, final String agentno, final Sort sort);
List<AgentUser> findByOrgiAndStatusAndSkillInAndAgentnoIsNot(final String orgi, final String status, final Collection<String> skill, final String agentno, final Sort sort);
List<AgentUser> findByOrgiAndStatusAndSkillInAndAgentnoIsNotAndChatbotopsIsFalse(final String orgi, final String status, final Collection<String> skill, final String agentno, final Sort sort);
List<AgentUser> findByOrgiAndStatusAndAgentno(final String orgi, final String status, final String agentno, final Sort defaultSort);
......
......@@ -41,4 +41,9 @@ public interface FbOTNRepository extends JpaRepository<FbOTN, String> {
@Modifying
@Query(nativeQuery = true, value = "update cs_fb_otn set sub_num = sub_num +1 where id = ?1")
void incOneSubNumById(final String id);
@Transactional
@Modifying
@Query(nativeQuery = true, value = "update cs_fb_otn set melink_num = melink_num +1 where id = ?1")
void incOneMelinkNumById(final String id);
}
......@@ -48,12 +48,14 @@
uploadText.hide();
json.url = data.url;
jsonInput.val(JSON.stringify(json));
jsonInput.trigger("change");
img.css('height', '130px');
});
});
textInput.bind("input propertychange", function (event) {
json.content = textInput.val();
jsonInput.val(JSON.stringify(json));
jsonInput.trigger("change");
});
select.change(function () {
if (select.val() == 'image') {
......@@ -66,8 +68,10 @@
json.type = 'text'
}
jsonInput.val(JSON.stringify(json));
jsonInput.trigger("change");
})
jsonInput.val(JSON.stringify(json));
jsonInput.trigger("change");
$this.append(jsonInput)
$this.append(select)
$this.append(box)
......
......@@ -682,10 +682,10 @@ script.
});
$('#quickReplyAgentBox').on('click', '.chooseAnswer', function () {
editor.html($(this).data('title'))
editor.html($(this).data('title') + "")
});
$('#quickReplyBox').on('click', '.chooseAnswer', function () {
editor.html($(this).data('title'))
editor.html($(this).data('title') + "")
});
......@@ -685,10 +685,10 @@ script.
});
$('#quickReplyAgentBox').on('click', '.chooseAnswer', function () {
editor.html($(this).data('title'))
editor.html($(this).data('title') + "")
});
$('#quickReplyBox').on('click', '.chooseAnswer', function () {
editor.html($(this).data('title'))
editor.html($(this).data('title') + "")
});
......@@ -681,10 +681,10 @@ script.
});
$('#ccaQuickReplyAgentBox').on('click', '.chooseAnswer', function () {
editor.html($(this).data('title'))
editor.html($(this).data('title') + "")
});
$('#ccaQuickReplyBox').on('click', '.chooseAnswer', function () {
editor.html($(this).data('title'))
editor.html($(this).data('title') + "")
});
......@@ -311,7 +311,7 @@ html
.ukefu-func-tab
ul
if models.contains("chatbot") && inviteData.ai && aiid
if !exchange || exchange == "true"
if exchange || exchange == "true"
li
a(href="/im/index.html?appid=" + appid + "&orgi=" + orgi + (aiid ? "&aiid=" + aiid : "") + "&ai=false" + (client ? "&client=" + client : '') + (type ? "&type=text" : "") + (skill ? "&skill=" + skill : '') + (agent ? "&agent=" + agent : '') + (title ? "&title=" + title : '') + (url ? "&url=" + url : '') + (traceid ? "&traceid=" + traceid : '') + "&userid=" + userid + "&sessionid=" + sessionid + "&t=" + pugHelper.currentTimeMillis()) 人工坐席
li.cur
......
......@@ -213,7 +213,7 @@ html
.ukefu-func-tab
ul
if models.contains("chatbot") && inviteData.ai && inviteData.ai == true && aiid
if !exchange || exchange == "true"
if exchange || exchange == "true"
li
a(href="/im/index.html?appid=" + appid + "&orgi=" + orgi + (aiid ? '&aiid=' + aiid : '') + "&ai=false" + (client ? '&client=' + client : '') + (type ? '&type=' + type : '') + (skill ? '&skill=' + skill : '') + (agent ? '&agent=' + agent : '') + "&userid=" + userid + "&sessionid=" + sessionid + "&t=" + pugHelper.currentTimeMillis()) 人工客服
li.cur
......
......@@ -54,7 +54,6 @@ else if inviteData.consult_invite_color == "6"
#ukefu-point-theme.ukefu-theme-color.theme1(class="ukefu-point-theme" + (inviteData.consult_vsitorbtn_model ? inviteData.consult_vsitorbtn_model : '1'), style=style + theme)
#ukefu-im-point-text.ukefu-im-point-text(style='cursor: pointer;' + text + ';line-height: 23px;font-size: 15px;text-align: center;margin: 0 auto;')
i(style="width:24px;height:24px;display: inline-block;font: normal normal normal 14px/1 FontAwesome;font-size: inherit;text-rendering: auto;-webkit-font-smoothing: antialiased;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAB60lEQVRIS7WV4TVsQRCEqyJABkSACBABLwJE8IjAigARIAMieCsCREAGjwja+eb03TO7O9ddrPm1Z29PV3dXdY31y8eL5I+ILUmbktYz/lXSs+2nofu9ABFBsjNJB5JWJT3MJNuR9CbpTtK5bUDnThMgIkaZnKSXtkkydyIC8BNJgI1sn88GzQFExI2kXUlHtsdDI+B7RBDPvUfbf+o7UwCZnHnv2qb9hU9EMEYKAuS4uzgByHapYqtvnkNoyRvE030Zaw0AScz7cijRZ9+Tv33b2xOAlOGjpLWvjmYWLEf1X9I2Mi4dRMRRtgVZ5WTgtaRX26cVmUj3lMtVzEPdeUTARVFfB4AsIbYG4Pe/0qbdxXERSaL7UapnKiYLIW5MTG8HGYjG6aAQlqNE+1RXVBYRUzH5H0SzF5MO2NqXJXHQ5dpAjbWKQL2jrSWo6MA2+zQlU2bOKOBi0MRaRVRq3OtcYHaT2YFDSQR8CSSTQ/itbXgpp+VFgCDbi5Z59ej+L6RKuqqTNwEqvWMbK2li97XxpSXwPhRTlPSOq7Zc99MHJxeQdt+6HcklYhdICmfonWKaZwgAh8RC8HmSXUjCjtcXtZQhAKrHGqiQUTynpTRfr1YLQwBomcq7HekdxbdG9JOF65XpMpLWOT4AygTtGd0Q7EsAAAAASUVORK5CYII=);")
br
| #{inviteData.consult_vsitorbtn_content ? inviteData.consult_vsitorbtn_content : '在线客服'}
if inviteData.skill == true && inviteData.consult_skill_fixed == false
#ichatContent.ichat-content.ichat-float-left(style='width:152px;display: block;font-size:14px;' + theme + ';box-shadow: 0 0 10px #DDDDDD;border: 1px solid #DDDDDD;overflow: hidden;text-align: left;')
......@@ -72,12 +71,17 @@ else if inviteData.consult_invite_color == "6"
else
img(src=baseUrl + '/images/title.jpg', style='width:140px;margin:0 5px;vertical-align: middle;')
div(style="padding:10px 5px;text-align:center;color:#555;")= inviteData.skill == true && inviteData.consult_skill_fixed == false && inviteData.consult_skill_msg ? inviteData.consult_skill_msg : ''
if skillGroups
for skill in skillGroups
- var skillNum = 0
for agent in agentList
- skillNum = skillNum + 1
| #{skillNum}
if agent.skills[skill.id]
- skillNum = skillNum + 1
div(style='padding:5px;color:#555;border:1px solid #dddddd;background-color:#efefef;')
a(href=baseUrl + '/im/text/' + appid + '.html?skill=' + skill.id + '&orgi=' + orgi, onclick='return openAgentChatDialog(this.href)', style='color: #777; text-decoration: none;') #{skill.name}(#{skillNum})
if inviteData.consult_skill_agent && inviteData.consult_skill_agent == true
ul(class="ichat-list-ul", style="border: 0 none;list-style: none outside none;margin: 0;padding: 0;width: 150px;")
if agentList
......
......@@ -794,6 +794,7 @@ CREATE TABLE `cs_fb_otn` (
`updatetime` DATETIME NOT NULL,
`sendtime` DATETIME NULL DEFAULT NULL,
`sub_num` INT(11) NOT NULL,
`melink_num` INT(11) NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='FB OTN';
USE `cosinee`;
-- -----------------
-- prepare variables
-- -----------------
SET @dbname = DATABASE ( );
SET @tablename = "cs_fb_otn";
SET @columnname = "melink_num";
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, " INT(11) DEFAULT 0 COMMENT 'Melink 点击数';" )
)
);
PREPARE alterIfNotExists
FROM
@preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
\ No newline at end of file
......@@ -55,12 +55,10 @@
</dependency>
<!-- pugjs, template engine surpass freemarker https://pugjs.org/ -->
<!-- hosted with Chatopera Nexus -->
<!-- https://gitlab.chatopera.com/cskefu/spring-pug4j -->
<dependency>
<groupId>de.neuland-bfi</groupId>
<artifactId>spring-pug4j</artifactId>
<version>2.0.0-alpha-4-SNAPSHOT</version>
<version>2.0.0-alpha-2</version>
</dependency>
<dependency>
......
......@@ -497,6 +497,7 @@ public class ApiChatbotController extends Handler {
} else if (c.getChannel().equals(Constants.CHANNEL_TYPE_MESSENGER)) {
FbMessenger fbMessenger = fbMessengerRepository.findOneByPageId(c.getSnsAccountIdentifier());
fbMessenger.setAiid(null);
fbMessenger.setAi(false);
fbMessengerRepository.save(fbMessenger);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册