|
|
@@ -3,6 +3,7 @@ package com.cyksj.service.corp.impl;
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
import cn.hutool.core.date.DateTime;
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
import cn.hutool.core.io.FileUtil;
|
|
|
import cn.hutool.core.util.RandomUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
@@ -572,6 +573,7 @@ public class CorpServiceImpl implements CorpService {
|
|
|
List<WxCpKfMsgListResp.WxCpKfMsgItem> enterSessionList = null;
|
|
|
List<WxCpKfMsgListResp.WxCpKfMsgItem> sessionStatusChanges = null;
|
|
|
List<WxCorpChatMsg> mergedMsgs = null;
|
|
|
+ List<WxCpKfMsgListResp.WxCpKfMsgItem> textList = null;
|
|
|
for (WxCpKfMsgListResp.WxCpKfMsgItem item : msgList) {
|
|
|
if (item.getEvent() != null && item.getEvent().getEventType().equals("enter_session")) {
|
|
|
//会话事件
|
|
|
@@ -597,23 +599,56 @@ public class CorpServiceImpl implements CorpService {
|
|
|
mergedMsg.setServicer_userid(item.getServicerUserId());
|
|
|
mergedMsg.setExternal_userid(item.getExternalUserId());
|
|
|
mergedMsg.setMsgid(item.getMsgId());
|
|
|
+ mergedMsg.setOrigin(item.getOrigin());
|
|
|
mergedMsgs.add(mergedMsg);
|
|
|
}
|
|
|
+ if (StrUtil.equals("text", item.getMsgType())) {
|
|
|
+ textList.add(item);
|
|
|
+ }
|
|
|
}
|
|
|
//进入会话事件
|
|
|
enterSessionEvent(corpKfAccount, corpKfAccountSessionConfig, corpId, enterSessionList);
|
|
|
//会话更变事件
|
|
|
sessionStatusChange(corpId, openKfId, sessionStatusChanges);
|
|
|
- //消息发送失败事件
|
|
|
- //拒收客户消息变更事件
|
|
|
//同步客服聊天记录
|
|
|
syncChatMsg(openKfId, mergedMsgs);
|
|
|
+ //同步满意度
|
|
|
+ syncSessionSatisfaction(openKfId, textList);
|
|
|
corpKfAccountSyncMsgProgress.setCursor(cursor);
|
|
|
+ //同步信息
|
|
|
while (wxCpKfMsgListResp.getHasMore() == 1) {
|
|
|
syncCorpKfMsg(corpKfAccount, corpKfAccountSessionConfig, corpId, wxCpKfMsgListResp.getNextCursor(), token, limit, corpKfAccountSyncMsgProgress);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private void syncSessionSatisfaction(String openKfId, List<WxCpKfMsgListResp.WxCpKfMsgItem> textList) {
|
|
|
+ Integer satisfaction = null;
|
|
|
+ for (WxCpKfMsgListResp.WxCpKfMsgItem item : textList) {
|
|
|
+ WxCorpTextMsg text = item.getText();
|
|
|
+ //自定义菜单id
|
|
|
+ if (text.getMenu_id()!=null) {
|
|
|
+ //满意
|
|
|
+ if ("101".equals(text.getMenu_id())) {
|
|
|
+ satisfaction = 1;
|
|
|
+ }
|
|
|
+ //一般
|
|
|
+ if ("102".equals(text.getMenu_id())) {
|
|
|
+ satisfaction = 2;
|
|
|
+ }
|
|
|
+ //不满意
|
|
|
+ if ("103".equals(text.getMenu_id())) {
|
|
|
+ satisfaction = 3;
|
|
|
+ }
|
|
|
+ if (satisfaction != null) {
|
|
|
+ corpKfServicerSessionRecordMapper.update(null, Wrappers.lambdaUpdate(CorpKfServicerSessionRecord.class)
|
|
|
+ .set(CorpKfServicerSessionRecord::getSatisfaction, satisfaction)
|
|
|
+ .eq(CorpKfServicerSessionRecord::getOpenKfId, openKfId)
|
|
|
+ .eq(CorpKfServicerSessionRecord::getMsgId, item.getMsgId()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private void syncChatMsg(String openKfId, List<WxCorpChatMsg> mergedMsgs) {
|
|
|
CorpKfAccountSessionChat corpKfAccountSessionChat = null;
|
|
|
for (WxCorpChatMsg mergedMsg : mergedMsgs) {
|
|
|
@@ -629,6 +664,7 @@ public class CorpServiceImpl implements CorpService {
|
|
|
corpKfAccountSessionChat.setMsgType(item.getMsgtype());
|
|
|
corpKfAccountSessionChat.setMsgContent(item.getMsg_content());
|
|
|
corpKfAccountSessionChat.setMsgid(mergedMsg.getMsgid());
|
|
|
+ corpKfAccountSessionChat.setOrign(mergedMsg.getOrigin());
|
|
|
corpKfAccountSessionChatMapper.insert(corpKfAccountSessionChat);
|
|
|
}
|
|
|
}
|
|
|
@@ -702,64 +738,81 @@ public class CorpServiceImpl implements CorpService {
|
|
|
log.info("external_userid:{}已有未结束的会话,无需分配", event.getExternalUserId());
|
|
|
return;
|
|
|
}
|
|
|
- //配置接待人员
|
|
|
- //是否有空闲人员
|
|
|
- int hour = DateTime.now().hour(true);
|
|
|
- corpKfAccountFollowMapper.selectList(Wrappers.lambdaQuery(CorpKfAccountFollow.class)
|
|
|
+ }
|
|
|
+ //是否设置非值班提示
|
|
|
+ if (corpKfAccountSessionConfig != null && StrUtil.isNotEmpty(corpKfAccountSessionConfig.getNoDutyTips())) {
|
|
|
+ DateTime now = DateTime.now();
|
|
|
+ int thisHour = DateUtil.hour(now, true);
|
|
|
+ //0-6 0周一
|
|
|
+ int dayOfWeek = DateUtil.dayOfWeek(now);
|
|
|
+ //是否值班期
|
|
|
+ Integer dutyHourCount = corpKfAccountFollowMapper.selectCount(Wrappers.lambdaQuery(CorpKfAccountFollow.class)
|
|
|
.eq(CorpKfAccountFollow::getOpenKfId, openKfId)
|
|
|
- .le(CorpKfAccountFollow::getStartTime, hour)
|
|
|
- .ge(CorpKfAccountFollow::getEndTime, hour));
|
|
|
- //获取接待人员列表
|
|
|
- CorpKfServicerResp corpKfServicerResp = wxCorpOps.getKfServicerList(corpId, openKfId);
|
|
|
- List<CorpKfServicerResp.CorpKfServicer> servicerList = corpKfServicerResp.getServicerList();
|
|
|
- //目前值班客服id
|
|
|
- List<String> corpKfServiceIds = new ArrayList<>();
|
|
|
- List<CorpKfServicerResp.CorpKfServicer> corpKfServicers = servicerList.stream().filter(servicer -> {
|
|
|
- if (servicer.getUserid() != null && servicer.getStatus() == 0) {
|
|
|
- corpKfServiceIds.add(servicer.getUserid());
|
|
|
- return true;
|
|
|
- }
|
|
|
- return false;
|
|
|
- }).collect(Collectors.toList());
|
|
|
- if (CollUtil.isEmpty(corpKfServicers)) {
|
|
|
- //非值班 移入等待池并发送非值班提示消息
|
|
|
- moveWaitingQueue(corpId, openKfId, event.getExternalUserId());
|
|
|
- String noDutyTips = corpKfAccountSessionConfig.getNoDutyTips();
|
|
|
- if (StrUtil.isNotEmpty(noDutyTips)) {
|
|
|
- //发送提示
|
|
|
- sendCorpKfTextTips(corpId, event.getExternalUserId(), openKfId, noDutyTips);
|
|
|
- }
|
|
|
- return;
|
|
|
- }
|
|
|
- //是否有空闲接待人员
|
|
|
- List<CorpKfServicerDto> corpKfServicerDtos = corpKfServicerSessionRecordMapper.getAvailableServicer(openKfId);
|
|
|
- if (CollUtil.isEmpty(corpKfServicerDtos)) {
|
|
|
- //暂无分配会话
|
|
|
- //随机分配一个客服
|
|
|
- CorpKfServicerResp.CorpKfServicer corpKfServicer = corpKfServicers.get(RandomUtil.randomInt(corpKfServicers.size()));
|
|
|
- //变更会话状态
|
|
|
- transCorpKfSessionToServicer(corpId, openKfId, corpKfServicer.getUserid(), event.getExternalUserId());
|
|
|
- }
|
|
|
- //筛选符合条件的客服
|
|
|
- //默认接入最少的优先分配 接待人最少的在集合前面
|
|
|
- //最多接待人数
|
|
|
- Integer maxNum = corpKfAccountSessionConfig.getMaxNum();
|
|
|
- List<CorpKfServicerDto> filterKfCs = corpKfServicerDtos.stream().filter(kfCs -> corpKfServiceIds.contains(kfCs.getServicerUserid()) && kfCs.getNum() < maxNum).collect(Collectors.toList());
|
|
|
- if (CollUtil.isEmpty(filterKfCs)) {
|
|
|
- //未有可接待的客服 移入等待池并发送进入等待池消息
|
|
|
+ .le(CorpKfAccountFollow::getStartTime, thisHour)
|
|
|
+ .ge(CorpKfAccountFollow::getEndTime, thisHour)
|
|
|
+ .apply(" and JSON_CONTAINS(duty_week,'\"%s\"')", dayOfWeek));
|
|
|
+ //非值班时间 发送通知
|
|
|
+ if (dutyHourCount == 0) {
|
|
|
+ //非值班时间 移入等待池并发送进入等待池消息
|
|
|
+ log.info("当前客服账号:{}处于非值班时间:{},将客服:{}移入等待池", openKfId, thisHour, event.getExternalUserId());
|
|
|
moveWaitingQueue(corpId, openKfId, event.getExternalUserId());
|
|
|
String queueTips = corpKfAccountSessionConfig.getQueueTips();
|
|
|
sendCorpKfTextTips(corpId, event.getExternalUserId(), openKfId, queueTips);
|
|
|
return;
|
|
|
}
|
|
|
- //选择第一个分配接待
|
|
|
- CorpKfServicerDto corpKfServicerDto = filterKfCs.get(0);
|
|
|
+ }
|
|
|
+ //获取接待人员列表
|
|
|
+ CorpKfServicerResp corpKfServicerResp = wxCorpOps.getKfServicerList(corpId, openKfId);
|
|
|
+ List<CorpKfServicerResp.CorpKfServicer> servicerList = corpKfServicerResp.getServicerList();
|
|
|
+ //目前值班客服id
|
|
|
+ List<String> corpKfServiceIds = new ArrayList<>();
|
|
|
+ List<CorpKfServicerResp.CorpKfServicer> corpKfServicers = servicerList.stream().filter(servicer -> {
|
|
|
+ if (servicer.getUserid() != null && servicer.getStatus() == 0) {
|
|
|
+ corpKfServiceIds.add(servicer.getUserid());
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ //客服是否已经开始值班
|
|
|
+ //没有值班人员 接入等待池
|
|
|
+ if (CollUtil.isEmpty(corpKfServicers)) {
|
|
|
+ moveWaitingQueue(corpId, openKfId, event.getExternalUserId());
|
|
|
+ String queueTips = corpKfAccountSessionConfig.getQueueTips();
|
|
|
+ sendCorpKfTextTips(corpId, event.getExternalUserId(), openKfId, queueTips);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //是否有空闲接待人员
|
|
|
+ List<CorpKfServicerDto> corpKfServicerDtos = corpKfServicerSessionRecordMapper.getAvailableServicer(openKfId);
|
|
|
+ //暂无分配会话 初始化
|
|
|
+ if (CollUtil.isEmpty(corpKfServicerDtos)) {
|
|
|
+ //随机分配一个客服
|
|
|
+ CorpKfServicerResp.CorpKfServicer corpKfServicer = corpKfServicers.get(RandomUtil.randomInt(corpKfServicers.size()));
|
|
|
//变更会话状态
|
|
|
- transCorpKfSessionToServicer(corpId, openKfId, corpKfServicerDto.getServicerUserid(), event.getExternalUserId());
|
|
|
+ transCorpKfSessionToServicer(corpId, openKfId, corpKfServicer.getUserid(), event.getExternalUserId());
|
|
|
+ return;
|
|
|
}
|
|
|
+ //筛选符合条件的客服
|
|
|
+ //默认接入最少的优先分配 接待人最少的在集合前面
|
|
|
+ //不超过最多接待人数
|
|
|
+ Integer maxNum = corpKfAccountSessionConfig.getMaxNum();
|
|
|
+ List<CorpKfServicerDto> filterKfCs = corpKfServicerDtos.stream().filter(kfCs -> corpKfServiceIds.contains(kfCs.getServicerUserid()) && kfCs.getNum() < maxNum).collect(Collectors.toList());
|
|
|
+ if (CollUtil.isEmpty(filterKfCs)) {
|
|
|
+ //未有可接待的客服 移入等待池并发送进入等待池消息
|
|
|
+ moveWaitingQueue(corpId, openKfId, event.getExternalUserId());
|
|
|
+ String queueTips = corpKfAccountSessionConfig.getQueueTips();
|
|
|
+ sendCorpKfTextTips(corpId, event.getExternalUserId(), openKfId, queueTips);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //选择第一个分配接待
|
|
|
+ CorpKfServicerDto corpKfServicerDto = filterKfCs.get(0);
|
|
|
+ //变更会话状态
|
|
|
+ transCorpKfSessionToServicer(corpId, openKfId, corpKfServicerDto.getServicerUserid(), event.getExternalUserId());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 变更用户会话状态
|
|
|
+ */
|
|
|
private void transCorpKfSessionToServicer(String corpId, String openKfId, String userid, String externalUserId) throws Exception {
|
|
|
//记录接待人员会话
|
|
|
CorpKfServicerSessionRecord corpKfServicerSessionRecord = new CorpKfServicerSessionRecord();
|
|
|
@@ -776,6 +829,9 @@ public class CorpServiceImpl implements CorpService {
|
|
|
* 发送微信客服会话文本消息
|
|
|
*/
|
|
|
public void sendCorpKfTextTips(String corpId, String externalUserid, String openKfId, String content) throws Exception {
|
|
|
+ if (StrUtil.isEmpty(content)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
WxCorpKfMsgSendRequest wxCpKfMsgSendRequest = new WxCorpKfMsgSendRequest();
|
|
|
wxCpKfMsgSendRequest.setMsgType("text");
|
|
|
wxCpKfMsgSendRequest.setToUser(externalUserid);
|