diff --git a/contact-center/app/src/main/java/com/chatopera/cc/activemq/AgentAuditSubscription.java b/contact-center/app/src/main/java/com/chatopera/cc/activemq/AgentAuditSubscription.java index aef06b4d..0a45e360 100644 --- a/contact-center/app/src/main/java/com/chatopera/cc/activemq/AgentAuditSubscription.java +++ b/contact-center/app/src/main/java/com/chatopera/cc/activemq/AgentAuditSubscription.java @@ -27,55 +27,59 @@ import com.chatopera.cc.socketio.client.NettyClients; import com.chatopera.cc.util.SerializeUtil; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import lombok.RequiredArgsConstructor; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jms.annotation.JmsListener; +import org.springframework.lang.NonNull; import org.springframework.stereotype.Component; +import java.util.Optional; + /** * 会话监控 */ @Component +@RequiredArgsConstructor public class AgentAuditSubscription { private final static Logger logger = LoggerFactory.getLogger(AgentAuditSubscription.class); - @Autowired - private Cache cache; + @NonNull + private final Cache cache; - @Autowired - private AgentAuditProxy agentAuditProxy; + @NonNull + private final AgentAuditProxy agentAuditProxy; - @Autowired - private AgentUserRepository agentUserRes; + @NonNull + private final AgentUserRepository agentUserRes; /** * 接收坐席会话监控消息 - * - * @param msg */ @JmsListener(destination = Constants.AUDIT_AGENT_MESSAGE, containerFactory = "jmsListenerContainerTopic") public void onMessage(final String msg) { logger.info("[onMessage] payload {}", msg); try { - final JsonObject json = new JsonParser().parse(msg).getAsJsonObject(); + final JsonObject json = JsonParser.parseString(msg).getAsJsonObject(); if (json.has("orgi") && json.has("data") && json.has("agentUserId") && json.has("event") && json.has("agentno")) { // 查找关联的会话监控信息 + String agentUserId = json.get("agentUserId").getAsString(); final AgentUserAudit agentUserAudit = cache.findOneAgentUserAuditByOrgiAndId( json.get("orgi").getAsString(), - json.get("agentUserId").getAsString()).orElseGet(() -> { - final AgentUser agentUser = agentUserRes.findOne(json.get("agentUserId").getAsString()); - if (agentUser != null) { + agentUserId).orElseGet(() -> { + Optional optional = agentUserRes.findById(agentUserId); + if (optional.isPresent()) { + final AgentUser agentUser = optional.get(); return agentAuditProxy.updateAgentUserAudits(agentUser); } else { logger.warn( - "[onMessage] can not find agent user by id {}", json.get("agentUserId").getAsString()); + "[onMessage] can not find agent user by id {}", agentUserId); } return null; }); @@ -101,7 +105,7 @@ public class AgentAuditSubscription { } else { logger.warn( "[onMessage] can not resolve agent user audit object for agent user id {}", - json.get("agentUserId").getAsString()); + agentUserId); } } else { throw new CSKefuException("Invalid payload."); diff --git a/contact-center/app/src/main/java/com/chatopera/cc/cache/Cache.java b/contact-center/app/src/main/java/com/chatopera/cc/cache/Cache.java index f3ada430..52dbd025 100644 --- a/contact-center/app/src/main/java/com/chatopera/cc/cache/Cache.java +++ b/contact-center/app/src/main/java/com/chatopera/cc/cache/Cache.java @@ -23,34 +23,51 @@ import com.chatopera.cc.persistence.repository.AgentUserRepository; import com.chatopera.cc.persistence.repository.OnlineUserRepository; import com.chatopera.cc.util.SerializeUtil; import com.chatopera.cc.util.freeswitch.model.CallCenterAgent; +import lombok.RequiredArgsConstructor; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.lang.NonNull; import org.springframework.stereotype.Component; import java.io.Serializable; import java.util.*; @Component +@RequiredArgsConstructor public class Cache { final static private Logger logger = LoggerFactory.getLogger(Cache.class); - @Autowired - private OnlineUserRepository onlineUserRes; + @NonNull + private final OnlineUserRepository onlineUserRes; - @Autowired - private AgentUserRepository agentUserRes; + @NonNull + private final AgentUserRepository agentUserRes; - @Autowired - private RedisCommand redisCommand; + @NonNull + private final RedisCommand redisCommand; + + /** + * Inline方法 + */ + private static Map convertFromStringToAgentStatus(final Map map) { + Map result = new HashMap<>(); + for (Map.Entry entry : map.entrySet()) { + AgentStatus obj = SerializeUtil.deserialize(entry.getValue()); + result.put(entry.getKey(), obj); + } + return result; + } + + private static OnlineUser convertFromStringToOnlineUser(final String serialized) { + return SerializeUtil.deserialize(serialized); + } /** * 获得就绪的坐席列表 * * @param orgi 租户 - * @return */ public Map getAgentStatusReadyByOrig(final String orgi) { Map agentStatuses = redisCommand.getHash(RedisKey.getAgentStatusReadyHashKey(orgi)); @@ -59,23 +76,19 @@ public class Cache { /** * 通过访客ID和ORGI获得访客坐席关联关系 - * - * @param userId - * @param orgi - * @return */ public Optional findOneAgentUserByUserIdAndOrgi(final String userId, final String orgi) { if (redisCommand.hasHashKV(RedisKey.getAgentUserInQueHashKey(orgi), userId)) { // 排队等待中 - return Optional.ofNullable((AgentUser) SerializeUtil.deserialize( + return Optional.ofNullable(SerializeUtil.deserialize( redisCommand.getHashKV(RedisKey.getAgentUserInQueHashKey(orgi), userId))); } else if (redisCommand.hasHashKV(RedisKey.getAgentUserInServHashKey(orgi), userId)) { // 服务中 - return Optional.ofNullable((AgentUser) SerializeUtil.deserialize( + return Optional.ofNullable(SerializeUtil.deserialize( redisCommand.getHashKV(RedisKey.getAgentUserInServHashKey(orgi), userId))); } else if (redisCommand.hasHashKV(RedisKey.getAgentUserEndHashKey(orgi), userId)) { // 已经结束 - return Optional.ofNullable((AgentUser) SerializeUtil.deserialize( + return Optional.ofNullable(SerializeUtil.deserialize( redisCommand.getHashKV(RedisKey.getAgentUserEndHashKey(orgi), userId))); } else { // 缓存中没有找到,继续到数据库查找 @@ -83,19 +96,15 @@ public class Cache { } } - /** * 返回排队中的客服列表 - * - * @param orgi - * @return */ public Map getAgentUsersInQueByOrgi(final String orgi) { Map agentUsers = redisCommand.getHash(RedisKey.getAgentUserInQueHashKey(orgi)); Map map = new HashMap<>(); for (final Map.Entry entry : agentUsers.entrySet()) { final AgentUser obj = SerializeUtil.deserialize(entry.getValue()); - map.put(obj.getId(), obj); + map.put(Objects.requireNonNull(obj).getId(), obj); } return map; } @@ -103,20 +112,13 @@ public class Cache { /** * 将访客ID从服务中队列中删除 * TODO 将访客对应的客服的服务列表变更 - * - * @param userid - * @param orgi */ public void deleteAgentUserInservByAgentUserIdAndOrgi(final String userid, final String orgi) { redisCommand.delHashKV(RedisKey.getAgentUserInServHashKey(orgi), userid); } - /** * 将访客ID从排队队列中删除 - * - * @param userid - * @param orgi */ public void deleteAgentUserInqueByAgentUserIdAndOrgi(final String userid, final String orgi) { redisCommand.delHashKV(RedisKey.getAgentUserInQueHashKey(orgi), userid); @@ -127,7 +129,6 @@ public class Cache { * * @param agentno 坐席ID * @param orgi 租户ID - * @return */ public AgentStatus findOneAgentStatusByAgentnoAndOrig(final String agentno, final String orgi) { String status = getAgentStatusStatus(agentno, orgi); @@ -140,15 +141,12 @@ public class Cache { String val = redisCommand.getHashKV(RedisKey.getAgentStatusHashKeyByStatusStr(orgi, status), agentno); AgentStatus result = SerializeUtil.deserialize(val); - logger.debug("[findOneAgentStatusByAgentnoAndOrig] result: username {}", result.getUsername()); + logger.debug("[findOneAgentStatusByAgentnoAndOrig] result: username {}", Objects.requireNonNull(result).getUsername()); return result; } /** * 更新坐席状态 - * - * @param agentStatus - * @param orgi */ public void putAgentStatusByOrgi(AgentStatus agentStatus, String orgi) { String pre = getAgentStatusStatus(agentStatus.getAgentno(), orgi); // 坐席前状态 @@ -160,14 +158,12 @@ public class Cache { RedisKey.getAgentStatusHashKeyByStatusStr(orgi, agentStatus.getStatus()), agentStatus.getAgentno(), SerializeUtil.serialize(agentStatus)); } - return; } else { // 之前存在,与将要更新的状态一致 if (StringUtils.equals(pre, agentStatus.getStatus())) { redisCommand.setHashKV( RedisKey.getAgentStatusHashKeyByStatusStr(orgi, pre), agentStatus.getAgentno(), SerializeUtil.serialize(agentStatus)); - return; } else { // 之前存在,而且与新状态不一致 redisCommand.delHashKV(RedisKey.getAgentStatusHashKeyByStatusStr(orgi, pre), agentStatus.getAgentno()); @@ -182,9 +178,6 @@ public class Cache { /** * 获得一个租户的就绪坐席状态 - * - * @param orgi - * @return */ public Map findAllReadyAgentStatusByOrgi(final String orgi) { List keys = new ArrayList<>(); @@ -196,9 +189,6 @@ public class Cache { /** * 获得一个租户的所有坐席状态 - * - * @param orgi - * @return */ public Map findAllAgentStatusByOrgi(final String orgi) { List keys = new ArrayList<>(); @@ -210,25 +200,8 @@ public class Cache { return convertFromStringToAgentStatus(map); } - - /** - * Inline方法 - */ - private static Map convertFromStringToAgentStatus(final Map map) { - Map result = new HashMap(); - for (Map.Entry entry : map.entrySet()) { - AgentStatus obj = SerializeUtil.deserialize(entry.getValue()); - result.put(entry.getKey(), obj); - } - return result; - } - - /** * Delete Agent Status - * - * @param agentno - * @param orgi */ public void deleteAgentStatusByAgentnoAndOrgi(final String agentno, final String orgi) { String status = getAgentStatusStatus(agentno, orgi); @@ -240,10 +213,6 @@ public class Cache { /** * 获得一个坐席的状态 agentStatus.status * 只返回大类状态 - * - * @param agentno - * @param orgi - * @return */ private String getAgentStatusStatus(final String agentno, final String orgi) { // 首先判断这个坐席的状态是READY还是BUSY,再去更新 @@ -256,24 +225,18 @@ public class Cache { } } - /** * 获得技能组的坐席状态 - * - * @param skill - * @param orgi - * @return */ public List getAgentStatusBySkillAndOrgi(final String skill, final String orgi) { Map map = findAllAgentStatusByOrgi(orgi); - List agentList = new ArrayList(); + List agentList = new ArrayList<>(); for (Map.Entry entry : map.entrySet()) { if (StringUtils.isNotBlank(skill)) { if (entry.getValue().getSkills() != null && entry.getValue().getSkills().containsKey(skill)) { agentList.add(entry.getValue()); - continue; } } else { agentList.add(entry.getValue()); @@ -282,21 +245,18 @@ public class Cache { return agentList; } + + //************************** + //* AgentUser相关 + //************************** + /** * 获得指定租户的就绪的坐席个数 - * - * @param orgi - * @return */ public int getAgentStatusReadySizeByOrgi(final String orgi) { return Math.toIntExact(redisCommand.getHashSize(RedisKey.getAgentStatusReadyHashKey(orgi))); } - - /************************** - * AgentUser相关 - **************************/ - /** * 更新坐席访客关联关系 * TODO 更新坐席的访客列表信息,增加新的访客信息 @@ -305,7 +265,6 @@ public class Cache { * 但是之前那个关联坐席的信息需要删除,要另行维护 * * @param agentUser 最新的agentUser的状态 - * @param orgi */ @AgentUserAspect.LinkAgentUser public void putAgentUserByOrgi(AgentUser agentUser, String orgi) { @@ -335,13 +294,8 @@ public class Cache { } } - /** * 获得一个客服服务中的访客列表 - * - * @param agentno - * @param orgi - * @return */ public List findInservAgentUsersByAgentnoAndOrgi(final String agentno, final String orgi) { logger.info("[findInservAgentUsersByAgentnoAndOrgi] agentno {}, orgi {}", agentno, orgi); @@ -358,10 +312,6 @@ public class Cache { /** * 获得一个坐席服务中的访客数量 - * - * @param agentno - * @param orgi - * @return */ public int getInservAgentUsersSizeByAgentnoAndOrgi(final String agentno, final String orgi) { return Math.toIntExact(redisCommand.getSetSize(RedisKey.getInServAgentUsersByAgentnoAndOrgi(agentno, orgi))); @@ -369,9 +319,6 @@ public class Cache { /** * 获得服务中的访客的数量 - * - * @param orgi - * @return */ public int getInservAgentUsersSizeByOrgi(final String orgi) { return redisCommand.getHashSize(RedisKey.getAgentUserInServHashKey(orgi)); @@ -379,9 +326,6 @@ public class Cache { /** * 获得等待中的访客的数量 - * - * @param orgi - * @return */ public int getInqueAgentUsersSizeByOrgi(final String orgi) { return redisCommand.getHashSize(RedisKey.getAgentUserInQueHashKey(orgi)); @@ -389,9 +333,6 @@ public class Cache { /** * Delete agentUser - * - * @param agentUser - * @param orgi */ @AgentUserAspect.LinkAgentUser public void deleteAgentUserByUserIdAndOrgi(final AgentUser agentUser, String orgi) { @@ -402,9 +343,8 @@ public class Cache { redisCommand.delHashKV(RedisKey.getAgentUserInServHashKey(orgi), agentUser.getUserid()); } else if (redisCommand.hasHashKV(RedisKey.getAgentUserEndHashKey(orgi), agentUser.getUserid())) { redisCommand.delHashKV(RedisKey.getAgentUserEndHashKey(orgi), agentUser.getUserid()); - } else { - // TODO 考虑是否有其他状态保存 } + // TODO 考虑是否有其他状态保存 } /*************************** @@ -425,20 +365,17 @@ public class Cache { } } - public void deleteConsultInviteBySnsidAndOrgi(final String snsid, final String orgi) { - redisCommand.delHashKV(RedisKey.getConsultInvitesByOrgi(orgi), snsid); - } - /**************************** * OnlineUser相关 ****************************/ + public void deleteConsultInviteBySnsidAndOrgi(final String snsid, final String orgi) { + redisCommand.delHashKV(RedisKey.getConsultInvitesByOrgi(orgi), snsid); + } + /** * 更新 onlineUser - * - * @param onlineUser - * @param orgi */ public void putOnlineUserByOrgi(final OnlineUser onlineUser, final String orgi) { // 此处onlineUser的id 与 onlineUser userId相同 @@ -448,10 +385,6 @@ public class Cache { /** * 获得 onlineUser - * - * @param id - * @param orgi - * @return */ public OnlineUser findOneOnlineUserByUserIdAndOrgi(final String id, final String orgi) { String serialized = redisCommand.getHashKV(RedisKey.getOnlineUserHashKey(orgi), id); @@ -463,16 +396,8 @@ public class Cache { } } - private static OnlineUser convertFromStringToOnlineUser(final String serialized) { - OnlineUser obj = SerializeUtil.deserialize(serialized); - return obj; - } - /** * 删除 onlineUser - * - * @param id - * @param orgi */ public void deleteOnlineUserByIdAndOrgi(final String id, final String orgi) { redisCommand.delHashKV(RedisKey.getOnlineUserHashKey(orgi), id); @@ -480,8 +405,6 @@ public class Cache { /** * 根据租户ID获得在线访客的列表大小 - * - * @param orgi */ public int getOnlineUserSizeByOrgi(final String orgi) { return redisCommand.getHashSize(RedisKey.getOnlineUserHashKey(orgi)); @@ -490,10 +413,6 @@ public class Cache { /** * 将在线访客从一个坐席的服务列表中删除 - * - * @param userid - * @param agentno - * @param orgi */ public void deleteOnlineUserIdFromAgentStatusByUseridAndAgentnoAndOrgi(final String userid, final String agentno, final String orgi) { redisCommand.removeSetVal(RedisKey.getInServAgentUsersByAgentnoAndOrgi(agentno, orgi), userid); @@ -509,16 +428,12 @@ public class Cache { } - /****************************** - * Callcenter Agent 相关 - ******************************/ + //****************************** + //* Callcenter Agent 相关 + //****************************** /** * 更新CallCenterAgent - * - * @param id - * @param orgi - * @param agent */ public void putCallCenterAgentByIdAndOrgi(final String id, final String orgi, final CallCenterAgent agent) { redisCommand.setHashKV(RedisKey.getCallCenterAgentHashKeyByOrgi(orgi), id, SerializeUtil.serialize(agent)); @@ -526,10 +441,6 @@ public class Cache { /** * 根据ID和租户ID获得CallCenterAgent - * - * @param id - * @param orgi - * @return */ public CallCenterAgent findOneCallCenterAgentByIdAndOrgi(final String id, final String orgi) { String serialized = redisCommand.getHashKV(RedisKey.getCallCenterAgentHashKeyByOrgi(orgi), id); @@ -542,9 +453,6 @@ public class Cache { /** * 删除CallCenterAgent - * - * @param id - * @param orgi */ public void deleteCallCenterAgentByIdAndOrgi(final String id, final String orgi) { redisCommand.delHashKV(RedisKey.getCallCenterAgentHashKeyByOrgi(orgi), id); @@ -553,9 +461,6 @@ public class Cache { /** * 根据租户ID获得所有的CallCenterAgent - * - * @param orgi - * @return */ public Map findAllCallCenterAgentsByOrgi(final String orgi) { Map map = redisCommand.getHash(RedisKey.getCallCenterAgentHashKeyByOrgi(orgi)); @@ -654,6 +559,7 @@ public class Cache { public List getSysDicItemsByCodeAndOrgi(final String code, final String orgi) { String serialized = redisCommand.getHashKV(RedisKey.getSysDicHashKeyByOrgi(orgi), code); if (serialized != null) { + //noinspection unchecked return (List) SerializeUtil.deserialize(serialized); } return null; @@ -724,6 +630,7 @@ public class Cache { public T findOneSystemByIdAndOrgi(final String id, final String orgi) { String serialized = redisCommand.getHashKV(RedisKey.getSystemHashKeyByOrgi(orgi), id); if (StringUtils.isNotBlank(serialized)) { + //noinspection unchecked return (T) SerializeUtil.deserialize(serialized); } return null; @@ -732,6 +639,7 @@ public class Cache { public List findOneSystemListByIdAndOrgi(final String id, final String orgi) { String serialized = redisCommand.getHashKV(RedisKey.getSystemHashKeyByOrgi(orgi), id); if (StringUtils.isNotBlank(serialized)) { + //noinspection unchecked return (List) SerializeUtil.deserialize(serialized); } return null; @@ -740,6 +648,7 @@ public class Cache { public Map findOneSystemMapByIdAndOrgi(final String id, final String orgi) { String serialized = redisCommand.getHashKV(RedisKey.getSystemHashKeyByOrgi(orgi), id); if (StringUtils.isNotBlank(serialized)) { + //noinspection unchecked return (Map) SerializeUtil.deserialize(serialized); } return null; @@ -781,6 +690,7 @@ public class Cache { public List findOneSessionConfigListByOrgi(final String orgi) { String serialized = redisCommand.get(RedisKey.getSessionConfigList(orgi)); if (StringUtils.isNotBlank(serialized)) { + //noinspection unchecked return (List) SerializeUtil.deserialize(serialized); } @@ -816,7 +726,7 @@ public class Cache { if (StringUtils.isBlank(serialized)) { return Optional.empty(); } - return Optional.ofNullable((AgentUserAudit) SerializeUtil.deserialize(serialized)); + return Optional.ofNullable(SerializeUtil.deserialize(serialized)); } public boolean existAgentUserAuditByOrgiAndId(final String orgi, final String agentUserId) { @@ -824,16 +734,13 @@ public class Cache { } - /****************************************** - * User Session 相关 - ******************************************/ + //****************************************** + //* User Session 相关 + //****************************************** + /** * 存入user的session,存储这组信息是为了让客户的账号只能在一个浏览器内登录使用 * 如果一个用户账号在多个浏览器使用,则登出之前的登录,只保留最后一个登录正常使用 - * - * @param agentno - * @param sessionId - * @param orgi */ public void putUserSessionByAgentnoAndSessionIdAndOrgi(final String agentno, final String sessionId, final String orgi) { redisCommand.setHashKV(RedisKey.getUserSessionKeyByOrgi(orgi), agentno, sessionId); diff --git a/contact-center/app/src/main/java/com/chatopera/cc/controller/api/ApiAgentUserController.java b/contact-center/app/src/main/java/com/chatopera/cc/controller/api/ApiAgentUserController.java index 7b39a8f0..89ff094c 100644 --- a/contact-center/app/src/main/java/com/chatopera/cc/controller/api/ApiAgentUserController.java +++ b/contact-center/app/src/main/java/com/chatopera/cc/controller/api/ApiAgentUserController.java @@ -1,388 +1,363 @@ -/* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2019 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.chatopera.cc.controller.api; - -import com.chatopera.cc.acd.ACDAgentDispatcher; -import com.chatopera.cc.acd.ACDAgentService; -import com.chatopera.cc.acd.basic.ACDComposeContext; -import com.chatopera.cc.acd.basic.ACDMessageHelper; -import com.chatopera.cc.basic.MainContext.*; -import com.chatopera.cc.basic.MainUtils; -import com.chatopera.cc.cache.Cache; -import com.chatopera.cc.controller.Handler; -import com.chatopera.cc.controller.api.request.RestUtils; -import com.chatopera.cc.exception.CSKefuException; -import com.chatopera.cc.model.*; -import com.chatopera.cc.peer.PeerSyncIM; -import com.chatopera.cc.persistence.repository.AgentServiceRepository; -import com.chatopera.cc.persistence.repository.AgentUserRepository; -import com.chatopera.cc.persistence.repository.UserRepository; -import com.chatopera.cc.proxy.AgentUserProxy; -import com.chatopera.cc.socketio.message.Message; -import com.chatopera.cc.util.Menu; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; -import java.util.Date; -import java.util.List; - -/** - * ACD服务 获取当前对话中的访客 - */ -@RestController -@RequestMapping("/api/agentuser") -public class ApiAgentUserController extends Handler { - - private final static Logger logger = LoggerFactory.getLogger(ApiAgentUserController.class); - - @Autowired - private ACDMessageHelper acdMessageHelper; - - @Autowired - private AgentUserProxy agentUserProxy; - - @Autowired - private ACDAgentService acdAgentService; - - @Autowired - private Cache cache; - - @Autowired - private PeerSyncIM peerSyncIM; - - @Autowired - private AgentUserRepository agentUserRes; - - @Autowired - private UserRepository userRes; - - @Autowired - private AgentServiceRepository agentServiceRes; - - @Autowired - private ACDAgentDispatcher acdAgentDispatcher; - - /** - * 获取当前对话中的访客 - * 坐席相关 RestAPI - * - * @param request - * @return - */ - @RequestMapping(method = RequestMethod.POST) - @Menu(type = "apps", subtype = "agentuser", access = true) - public ResponseEntity operations(HttpServletRequest request, @RequestBody final String body, @Valid String q) { - logger.info("[operations] body {}, q {}", body, q); - final JsonObject j = StringUtils.isBlank(body) ? (new JsonObject()) : (new JsonParser()).parse( - body).getAsJsonObject(); - JsonObject json = new JsonObject(); - HttpHeaders headers = RestUtils.header(); - - if (!j.has("ops")) { - json.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_1); - json.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的请求参数。"); - } else { - switch (StringUtils.lowerCase(j.get("ops").getAsString())) { - case "inserv": - json = inserv(request, j); - break; - case "withdraw": - json = withdraw(request, j); - break; - case "end": - json = end(request, j); - break; - case "transout": - json = transout(request, j); - break; - default: - json.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_2); - json.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的操作。"); - } - } - - return new ResponseEntity(json.toString(), headers, HttpStatus.OK); - } - - /** - * 执行坐席转接 - * 将会话转接给别人 - * - * @param request - * @param payload - * @return - */ - private JsonObject transout(final HttpServletRequest request, final JsonObject payload) { - logger.info("[transout] payload ", payload.toString()); - final String orgi = super.getOrgi(request); - final User logined = super.getUser(request); - JsonObject resp = new JsonObject(); - - /** - * 必填参数 - */ - // 目标坐席 - final String transAgentId = payload.get("agentno").getAsString(); - // 当前会话的ID - final String agentUserId = payload.get("agentUserId").getAsString(); - // 坐席服务ID - final String agentServiceId = payload.get("agentServiceId").getAsString(); - - if (StringUtils.isNotBlank(agentUserId) && - StringUtils.isNotBlank(transAgentId) && - StringUtils.isNotBlank(agentServiceId)) { - final User targetAgent = userRes.findOne(transAgentId); - final AgentService agentService = agentServiceRes.findByIdAndOrgi(agentServiceId, orgi); - - /** - * 更新AgentUser - */ - final AgentUser agentUser = agentUserProxy.findOne(agentUserId).orElseGet(null); - if (agentUser != null) { - final AgentUserAudit agentAudits = cache.findOneAgentUserAuditByOrgiAndId(orgi, agentUserId).orElseGet( - null); - - // 当前服务于访客的坐席 - final String currentAgentno = agentUser.getAgentno(); - // 当前访客的ID - final String userId = agentUser.getUserid(); - - logger.info( - "[transout] agentuserid {} \n target agent id {}, \n current agent id {}, onlineuserid {}", - agentUserId, transAgentId, currentAgentno, userId); - - - // 检查权限 - if ((!logined.isAdmin()) && (!StringUtils.equals( - agentUser.getAgentno(), - logined.getId())) && (!isTransPermissionAllowed( - agentAudits, logined))) { - // 1. 不是超级用户;2. 也是不是会话的所有者; 3. 也不是坐席监控人员 - logger.info("[end] Permission not fulfill."); - resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3); - resp.addProperty(RestUtils.RESP_KEY_ERROR, "Permission denied."); - return resp; - } - - agentUser.setAgentno(transAgentId); - agentUser.setAgentname(targetAgent.getUname()); - agentUserRes.save(agentUser); - - /** - * 坐席状态 - */ - // 转接目标坐席 - final AgentStatus transAgentStatus = cache.findOneAgentStatusByAgentnoAndOrig(transAgentId, orgi); - - // 转接源坐席 - final AgentStatus currentAgentStatus = cache.findOneAgentStatusByAgentnoAndOrig(currentAgentno, orgi); - - if (StringUtils.equals( - AgentUserStatusEnum.INSERVICE.toString(), - agentUser.getStatus())) { //转接 , 发送消息给 目标坐席 - // 更新当前坐席的服务访客列表 - if (currentAgentStatus != null) { - cache.deleteOnlineUserIdFromAgentStatusByUseridAndAgentnoAndOrgi(userId, currentAgentno, orgi); - agentUserProxy.updateAgentStatus(currentAgentStatus, orgi); - } - - if (transAgentStatus != null) { - agentService.setAgentno(transAgentId); - agentService.setAgentusername(transAgentStatus.getUsername()); - } - - // 转接坐席提示消息 - Message outMessage = new Message(); - outMessage.setMessage( - acdMessageHelper.getSuccessMessage(agentService, agentUser.getChannel(), orgi)); - outMessage.setMessageType(MediaType.TEXT.toString()); - outMessage.setCalltype(CallType.IN.toString()); - outMessage.setCreatetime(MainUtils.dateFormate.format(new Date())); - outMessage.setAgentUser(agentUser); - outMessage.setAgentService(agentService); - - if (StringUtils.isNotBlank(agentUser.getUserid())) { - peerSyncIM.send( - ReceiverType.VISITOR, - ChannelType.toValue(agentUser.getChannel()), - agentUser.getAppid(), - MessageType.STATUS, - agentUser.getUserid(), - outMessage, - true); - } - - // 通知转接消息给新坐席 - outMessage.setChannelMessage(agentUser); - outMessage.setAgentUser(agentUser); - peerSyncIM.send( - ReceiverType.AGENT, ChannelType.WEBIM, - agentUser.getAppid(), MessageType.NEW, agentService.getAgentno(), - outMessage, true); - - // 通知消息给前坐席 - if (!StringUtils.equals(logined.getId(), currentAgentno)) { - // 如果当前坐席不是登录用户,因为登录用户会从RestAPI返回转接的结果 - // 该登录用户可能是坐席监控或当前坐席,那么,如果是坐席监控,就有必要 - // 通知前坐席这个事件 - peerSyncIM.send(ReceiverType.AGENT, ChannelType.WEBIM, agentUser.getAppid(), - MessageType.TRANSOUT, - currentAgentno, outMessage, true); - } - } - - if (agentService != null) { - agentService.setAgentno(transAgentId); - if (payload.has("memo") && StringUtils.isNotBlank(payload.get("memo").getAsString())) { - agentService.setTransmemo(payload.get("memo").getAsString()); - } - agentService.setTrans(true); - agentService.setTranstime(new Date()); - agentServiceRes.save(agentService); - } - - resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_SUCC); - resp.addProperty(RestUtils.RESP_KEY_DATA, "success"); - } else { - resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_4); - resp.addProperty(RestUtils.RESP_KEY_ERROR, "Can not find agent user."); - } - } else { - resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_5); - resp.addProperty(RestUtils.RESP_KEY_ERROR, "Invalid params."); - } - - return resp; - } - - /** - * 结束对话 - * 如果当前对话属于登录用户或登录用户为超级用户,则可以结束这个对话 - * - * @param request - * @param payload - * @return - */ - private JsonObject end(final HttpServletRequest request, final JsonObject payload) { - logger.info("[end] payload {}", payload.toString()); - final String orgi = super.getOrgi(request); - final User logined = super.getUser(request); - JsonObject resp = new JsonObject(); - - final AgentUser agentUser = agentUserRes.findByIdAndOrgi(payload.get("id").getAsString(), orgi); - if (agentUser != null) { - if ((StringUtils.equals( - logined.getId(), agentUser.getAgentno()) || logined.isAdmin())) { - // 删除访客-坐席关联关系,包括缓存 - try { - acdAgentService.finishAgentUser(agentUser, orgi); - } catch (CSKefuException e) { - // 未能删除成功 - logger.error("[end]", e); - } - resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_SUCC); - resp.addProperty(RestUtils.RESP_KEY_DATA, "success"); - } else { - logger.info("[end] Permission not fulfill."); - resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3); - resp.addProperty(RestUtils.RESP_KEY_ERROR, "Permission denied."); - } - } else { - resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_4); - resp.addProperty(RestUtils.RESP_KEY_ERROR, "Agent User not found."); - } - - return resp; - } - - /** - * 撤退一个坐席 - * 将当前坐席服务中的访客分配给其他就绪的坐席 - * - * @param request - * @param j - * @return - */ - private JsonObject withdraw(final HttpServletRequest request, final JsonObject j) { - JsonObject resp = new JsonObject(); - ACDComposeContext ctx = new ACDComposeContext(); - ctx.setAgentno(super.getUser(request).getId()); - ctx.setOrgi(super.getOrgi(request)); - acdAgentDispatcher.dequeue(ctx); - resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_SUCC); - return resp; - } - - - /** - * 获得当前访客服务中的访客信息 - * 获取当前正在对话的访客信息,包含多种渠道来源的访客 - * - * @param request - * @param j - * @return - */ - private JsonObject inserv(final HttpServletRequest request, final JsonObject j) { - JsonObject resp = new JsonObject(); - JsonArray data = new JsonArray(); - - List lis = cache.findInservAgentUsersByAgentnoAndOrgi( - super.getUser(request).getId(), super.getOrgi(request)); - for (final AgentUser au : lis) { - JsonObject obj = new JsonObject(); - obj.addProperty("id", au.getId()); - obj.addProperty("userid", au.getUserid()); - obj.addProperty("status", au.getStatus()); - obj.addProperty("agentno", au.getAgentno()); - obj.addProperty("channel", au.getChannel()); - obj.addProperty("nickname", au.getNickname()); - data.add(obj); - } - resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_SUCC); - resp.add("data", data); - - return resp; - } - - /** - * 检查是否具备该会话的坐席监控权限 - * - * @param agentUserAudit - * @param user - * @return - */ - private boolean isTransPermissionAllowed(final AgentUserAudit agentUserAudit, final User user) { - if (agentUserAudit != null && agentUserAudit.getSubscribers().containsKey(user.getId())) { - return true; - } - return false; - } -} +/* + * Copyright (C) 2017 优客服-多渠道客服系统 + * Modifications copyright (C) 2018-2019 Chatopera Inc, + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.chatopera.cc.controller.api; + +import com.chatopera.cc.acd.ACDAgentDispatcher; +import com.chatopera.cc.acd.ACDAgentService; +import com.chatopera.cc.acd.basic.ACDComposeContext; +import com.chatopera.cc.acd.basic.ACDMessageHelper; +import com.chatopera.cc.basic.MainContext.*; +import com.chatopera.cc.basic.MainUtils; +import com.chatopera.cc.cache.Cache; +import com.chatopera.cc.controller.Handler; +import com.chatopera.cc.controller.api.request.RestUtils; +import com.chatopera.cc.exception.CSKefuException; +import com.chatopera.cc.model.*; +import com.chatopera.cc.peer.PeerSyncIM; +import com.chatopera.cc.persistence.repository.AgentServiceRepository; +import com.chatopera.cc.persistence.repository.AgentUserRepository; +import com.chatopera.cc.persistence.repository.UserRepository; +import com.chatopera.cc.proxy.AgentUserProxy; +import com.chatopera.cc.socketio.message.Message; +import com.chatopera.cc.util.Menu; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.util.Date; +import java.util.List; + +/** + * ACD服务 获取当前对话中的访客 + */ +@RestController +@RequestMapping("/api/agentuser") +@RequiredArgsConstructor +public class ApiAgentUserController extends Handler { + + private final static Logger logger = LoggerFactory.getLogger(ApiAgentUserController.class); + + @org.springframework.lang.NonNull + private final ACDMessageHelper acdMessageHelper; + + @org.springframework.lang.NonNull + private final AgentUserProxy agentUserProxy; + + @org.springframework.lang.NonNull + private final ACDAgentService acdAgentService; + + @org.springframework.lang.NonNull + private final Cache cache; + + @org.springframework.lang.NonNull + private final PeerSyncIM peerSyncIM; + + @org.springframework.lang.NonNull + private final AgentUserRepository agentUserRes; + + @org.springframework.lang.NonNull + private final UserRepository userRes; + + @org.springframework.lang.NonNull + private final AgentServiceRepository agentServiceRes; + + @org.springframework.lang.NonNull + private final ACDAgentDispatcher acdAgentDispatcher; + + /** + * 获取当前对话中的访客 + * 坐席相关 RestAPI + */ + @RequestMapping(method = RequestMethod.POST) + @Menu(type = "apps", subtype = "agentuser", access = true) + public ResponseEntity operations(HttpServletRequest request, @RequestBody final String body, @Valid String q) { + logger.info("[operations] body {}, q {}", body, q); + final JsonObject j = StringUtils.isBlank(body) ? new JsonObject() : JsonParser.parseString(body).getAsJsonObject(); + JsonObject json = new JsonObject(); + HttpHeaders headers = RestUtils.header(); + + if (!j.has("ops")) { + json.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_1); + json.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的请求参数。"); + } else { + switch (StringUtils.lowerCase(j.get("ops").getAsString())) { + case "inserv": + json = inserv(request); + break; + case "withdraw": + json = withdraw(request); + break; + case "end": + json = end(request, j); + break; + case "transout": + json = transout(request, j); + break; + default: + json.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_2); + json.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的操作。"); + } + } + + return new ResponseEntity<>(json.toString(), headers, HttpStatus.OK); + } + + /** + * 执行坐席转接 + * 将会话转接给别人 + */ + private JsonObject transout(final HttpServletRequest request, final JsonObject payload) { + logger.info("[transout] payload {}", payload.toString()); + final String orgi = super.getOrgi(request); + final User logined = super.getUser(request); + JsonObject resp = new JsonObject(); + + /* + * 必填参数 + */ + // 目标坐席 + final String transAgentId = payload.get("agentno").getAsString(); + // 当前会话的ID + final String agentUserId = payload.get("agentUserId").getAsString(); + // 坐席服务ID + final String agentServiceId = payload.get("agentServiceId").getAsString(); + + if (StringUtils.isNotBlank(agentUserId) && + StringUtils.isNotBlank(transAgentId) && + StringUtils.isNotBlank(agentServiceId)) { + final User targetAgent = userRes.findById(transAgentId) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, String.format("Agent %s not found", transAgentId))); + final AgentService agentService = agentServiceRes.findByIdAndOrgi(agentServiceId, orgi); + + /* + * 更新AgentUser + */ + final AgentUser agentUser = agentUserProxy.findOne(agentUserId).orElse(null); + if (agentUser != null) { + final AgentUserAudit agentAudits = cache.findOneAgentUserAuditByOrgiAndId(orgi, agentUserId).orElse(null); + + // 当前服务于访客的坐席 + final String currentAgentno = agentUser.getAgentno(); + // 当前访客的ID + final String userId = agentUser.getUserid(); + + logger.info( + "[transout] agentuserid {} \n target agent id {}, \n current agent id {}, onlineuserid {}", + agentUserId, transAgentId, currentAgentno, userId); + + + // 检查权限 + if ((!logined.isAdmin()) && (!StringUtils.equals( + agentUser.getAgentno(), + logined.getId())) && (!isTransPermissionAllowed( + agentAudits, logined))) { + // 1. 不是超级用户;2. 也是不是会话的所有者; 3. 也不是坐席监控人员 + logger.info("[end] Permission not fulfill."); + resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3); + resp.addProperty(RestUtils.RESP_KEY_ERROR, "Permission denied."); + return resp; + } + + agentUser.setAgentno(transAgentId); + agentUser.setAgentname(targetAgent.getUname()); + agentUserRes.save(agentUser); + + /* + * 坐席状态 + */ + // 转接目标坐席 + final AgentStatus transAgentStatus = cache.findOneAgentStatusByAgentnoAndOrig(transAgentId, orgi); + + // 转接源坐席 + final AgentStatus currentAgentStatus = cache.findOneAgentStatusByAgentnoAndOrig(currentAgentno, orgi); + + if (StringUtils.equals( + AgentUserStatusEnum.INSERVICE.toString(), + agentUser.getStatus())) { //转接 , 发送消息给 目标坐席 + // 更新当前坐席的服务访客列表 + if (currentAgentStatus != null) { + cache.deleteOnlineUserIdFromAgentStatusByUseridAndAgentnoAndOrgi(userId, currentAgentno, orgi); + agentUserProxy.updateAgentStatus(currentAgentStatus, orgi); + } + + if (transAgentStatus != null) { + agentService.setAgentno(transAgentId); + agentService.setAgentusername(transAgentStatus.getUsername()); + } + + // 转接坐席提示消息 + Message outMessage = new Message(); + outMessage.setMessage( + acdMessageHelper.getSuccessMessage(agentService, agentUser.getChannel(), orgi)); + outMessage.setMessageType(MediaType.TEXT.toString()); + outMessage.setCalltype(CallType.IN.toString()); + outMessage.setCreatetime(MainUtils.dateFormate.format(new Date())); + outMessage.setAgentUser(agentUser); + outMessage.setAgentService(agentService); + + if (StringUtils.isNotBlank(agentUser.getUserid())) { + peerSyncIM.send( + ReceiverType.VISITOR, + ChannelType.toValue(agentUser.getChannel()), + agentUser.getAppid(), + MessageType.STATUS, + agentUser.getUserid(), + outMessage, + true); + } + + // 通知转接消息给新坐席 + outMessage.setChannelMessage(agentUser); + outMessage.setAgentUser(agentUser); + peerSyncIM.send( + ReceiverType.AGENT, ChannelType.WEBIM, + agentUser.getAppid(), MessageType.NEW, agentService.getAgentno(), + outMessage, true); + + // 通知消息给前坐席 + if (!StringUtils.equals(logined.getId(), currentAgentno)) { + // 如果当前坐席不是登录用户,因为登录用户会从RestAPI返回转接的结果 + // 该登录用户可能是坐席监控或当前坐席,那么,如果是坐席监控,就有必要 + // 通知前坐席这个事件 + peerSyncIM.send(ReceiverType.AGENT, ChannelType.WEBIM, agentUser.getAppid(), + MessageType.TRANSOUT, + currentAgentno, outMessage, true); + } + } + + if (agentService != null) { + agentService.setAgentno(transAgentId); + if (payload.has("memo") && StringUtils.isNotBlank(payload.get("memo").getAsString())) { + agentService.setTransmemo(payload.get("memo").getAsString()); + } + agentService.setTrans(true); + agentService.setTranstime(new Date()); + agentServiceRes.save(agentService); + } + + resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_SUCC); + resp.addProperty(RestUtils.RESP_KEY_DATA, "success"); + } else { + resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_4); + resp.addProperty(RestUtils.RESP_KEY_ERROR, "Can not find agent user."); + } + } else { + resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_5); + resp.addProperty(RestUtils.RESP_KEY_ERROR, "Invalid params."); + } + + return resp; + } + + /** + * 结束对话 + * 如果当前对话属于登录用户或登录用户为超级用户,则可以结束这个对话 + */ + private JsonObject end(final HttpServletRequest request, final JsonObject payload) { + logger.info("[end] payload {}", payload.toString()); + final String orgi = super.getOrgi(request); + final User logined = super.getUser(request); + JsonObject resp = new JsonObject(); + + final AgentUser agentUser = agentUserRes.findByIdAndOrgi(payload.get("id").getAsString(), orgi); + if (agentUser != null) { + if ((StringUtils.equals( + logined.getId(), agentUser.getAgentno()) || logined.isAdmin())) { + // 删除访客-坐席关联关系,包括缓存 + try { + acdAgentService.finishAgentUser(agentUser, orgi); + } catch (CSKefuException e) { + // 未能删除成功 + logger.error("[end]", e); + } + resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_SUCC); + resp.addProperty(RestUtils.RESP_KEY_DATA, "success"); + } else { + logger.info("[end] Permission not fulfill."); + resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3); + resp.addProperty(RestUtils.RESP_KEY_ERROR, "Permission denied."); + } + } else { + resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_4); + resp.addProperty(RestUtils.RESP_KEY_ERROR, "Agent User not found."); + } + + return resp; + } + + /** + * 撤退一个坐席 + * 将当前坐席服务中的访客分配给其他就绪的坐席 + */ + private JsonObject withdraw(final HttpServletRequest request) { + JsonObject resp = new JsonObject(); + ACDComposeContext ctx = new ACDComposeContext(); + ctx.setAgentno(super.getUser(request).getId()); + ctx.setOrgi(super.getOrgi(request)); + acdAgentDispatcher.dequeue(ctx); + resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_SUCC); + return resp; + } + + + /** + * 获得当前访客服务中的访客信息 + * 获取当前正在对话的访客信息,包含多种渠道来源的访客 + */ + private JsonObject inserv(final HttpServletRequest request) { + JsonObject resp = new JsonObject(); + JsonArray data = new JsonArray(); + + List lis = cache.findInservAgentUsersByAgentnoAndOrgi( + super.getUser(request).getId(), super.getOrgi(request)); + for (final AgentUser au : lis) { + JsonObject obj = new JsonObject(); + obj.addProperty("id", au.getId()); + obj.addProperty("userid", au.getUserid()); + obj.addProperty("status", au.getStatus()); + obj.addProperty("agentno", au.getAgentno()); + obj.addProperty("channel", au.getChannel()); + obj.addProperty("nickname", au.getNickname()); + data.add(obj); + } + resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_SUCC); + resp.add("data", data); + + return resp; + } + + /** + * 检查是否具备该会话的坐席监控权限 + */ + private boolean isTransPermissionAllowed(final AgentUserAudit agentUserAudit, final User user) { + return agentUserAudit != null && agentUserAudit.getSubscribers().containsKey(user.getId()); + } +} 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 7731c674..4aa4bee0 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 @@ -618,7 +618,7 @@ public class AgentAuditController extends Handler { payload.put("orgi", orgi); ModelAndView view = end(request, agentuserid); // 更新或创建黑名单 - blackEntityProxy.updateOrCreateBlackEntity(blackEntity, logined, userid, orgi, agentserviceid, agentuserid); + blackEntityProxy.updateOrCreateBlackEntity(blackEntity, logined, userid, orgi, agentserviceid); // 创建定时任务 取消拉黑 brokerPublisher.send( 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 4cf808c8..724ea32c 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 @@ -748,7 +748,7 @@ ModelAndView view = end(request, agentuserid); // 更新或创建黑名单 - blackEntityProxy.updateOrCreateBlackEntity(blackEntity, logined, userid, orgi, agentserviceid, agentuserid); + blackEntityProxy.updateOrCreateBlackEntity(blackEntity, logined, userid, orgi, agentserviceid); // 创建定时任务 取消拉黑 brokerPublisher.send( diff --git a/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/TenantController.java b/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/TenantController.java index f835de94..4fc61dfa 100644 --- a/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/TenantController.java +++ b/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/TenantController.java @@ -1,285 +1,286 @@ -/* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2019 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.chatopera.cc.controller.apps; - -import com.chatopera.cc.basic.MainContext; -import com.chatopera.cc.cache.Cache; -import com.chatopera.cc.controller.Handler; -import com.chatopera.cc.model.*; -import com.chatopera.cc.persistence.repository.*; -import com.chatopera.cc.proxy.OnlineUserProxy; -import com.chatopera.cc.util.Menu; -import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Controller; -import org.springframework.ui.ModelMap; -import org.springframework.util.FileCopyUtils; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.servlet.ModelAndView; - -import javax.servlet.http.HttpServletRequest; -import javax.validation.Valid; -import java.io.File; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -@Controller -@RequestMapping("/apps/tenant") -public class TenantController extends Handler { - - @Autowired - private TenantRepository tenantRes; - - @Autowired - private OrgiSkillRelRepository orgiSkillRelRes; - - @Autowired - private OrganRepository organRes; - - @Autowired - private OrganizationRepository organizationRes; - - @Autowired - private AgentUserRepository agentUserRepository; - - @Autowired - private Cache cache; - - @Value("${web.upload-path}") - private String path; - - @RequestMapping("/index") - @Menu(type = "apps", subtype = "tenant") - public ModelAndView index( - ModelMap map, final HttpServletRequest request, - final @Valid String msg, - final @Valid String currentorgi, - final @Valid String currentname) throws IOException { - if (super.isEnabletneant()) { - // 系统管理员开启多租户访问 - if (super.getUser(request).isAdmin()) { - map.addAttribute("tenantList", tenantRes.findByOrgid(super.getOrgid(request))); - } else { - List orgiSkillRelList = orgiSkillRelRes.findBySkillidIn( - new ArrayList<>((super.getUser(request)).getAffiliates())); - List tenantList = null; - if (!orgiSkillRelList.isEmpty()) { - tenantList = new ArrayList(); - for (OrgiSkillRel orgiSkillRel : orgiSkillRelList) { - Tenant t = tenantRes.findById(orgiSkillRel.getOrgi()); - if (t != null) { - tenantList.add(t); - } - } - } - map.addAttribute("tenantList", tenantList); - } - } else { - map.addAttribute("tenantList", tenantRes.findById(super.getOrgi(request))); - } - map.addAttribute("organization", organizationRes.findById(super.getUser(request).getOrgid())); - map.addAttribute("msg", msg); - map.addAttribute("currentorgi", currentorgi); - if (currentname != null) { - map.addAttribute("currentname", URLDecoder.decode(currentname, "UTF-8")); - } - return request(super.createRequestPageTempletResponse("/apps/tenant/index")); - } - - @RequestMapping("/add") - @Menu(type = "apps", subtype = "tenant") - public ModelAndView add(ModelMap map, HttpServletRequest request) { - if (super.isTenantshare()) { - map.addAttribute("isShowSkillGroups", true); - List organList = organRes.findByOrgiAndOrgid( - super.getOrgiByTenantshare(request), super.getOrgid(request)); - map.addAttribute("skillGroups", organList); - } - return request(super.createRequestPageTempletResponse("/apps/tenant/add")); - } - - @RequestMapping("/save") - @Menu(type = "apps", subtype = "tenant") - public ModelAndView save(HttpServletRequest request, @Valid Tenant tenant, @RequestParam(value = "tenantpic", required = false) MultipartFile tenantpic, @Valid String skills) throws NoSuchAlgorithmException, IOException { - Tenant tenanttemp = tenantRes.findByOrgidAndTenantname(super.getOrgid(request), tenant.getTenantname()); - if (tenanttemp != null) { - return request(super.createRequestPageTempletResponse("redirect:/apps/tenant/index.html?msg=tenantexist")); - } - tenantRes.save(tenant); - if (tenantpic != null && tenantpic.getOriginalFilename().lastIndexOf(".") > 0) { - File logoDir = new File(path, "tenantpic"); - if (!logoDir.exists()) { - logoDir.mkdirs(); - } - String fileName = "tenantpic/" + tenant.getId() + tenantpic.getOriginalFilename().substring( - tenantpic.getOriginalFilename().lastIndexOf(".")); - FileCopyUtils.copy(tenantpic.getBytes(), new File(path, fileName)); - tenant.setTenantlogo(fileName); - } - String tenantid = tenant.getId(); - List orgiSkillRelList = orgiSkillRelRes.findByOrgi(tenantid); - orgiSkillRelRes.delete(orgiSkillRelList); - if (!StringUtils.isBlank(skills)) { - String[] skillsarray = skills.split(","); - for (String skill : skillsarray) { - OrgiSkillRel rel = new OrgiSkillRel(); - rel.setOrgi(tenant.getId()); - rel.setSkillid(skill); - rel.setCreater(super.getUser(request).getId()); - rel.setCreatetime(new Date()); - orgiSkillRelRes.save(rel); - } - } - if (!StringUtils.isBlank(super.getUser(request).getOrgid())) { - tenant.setOrgid(super.getUser(request).getOrgid()); - } else { - tenant.setOrgid(MainContext.SYSTEM_ORGI); - } - tenantRes.save(tenant); - OnlineUserProxy.clean(tenantid); - return request(super.createRequestPageTempletResponse("redirect:/apps/tenant/index")); - } - - @RequestMapping("/edit") - @Menu(type = "apps", subtype = "tenant") - public ModelAndView edit(ModelMap map, HttpServletRequest request, @Valid String id) { - if (super.isTenantshare()) { - map.addAttribute("isShowSkillGroups", true); - List organList = organRes.findByOrgiAndOrgid( - super.getOrgiByTenantshare(request), super.getOrgid(request)); - map.addAttribute("skillGroups", organList); - List orgiSkillRelList = orgiSkillRelRes.findByOrgi(id); - map.addAttribute("orgiSkillRelList", orgiSkillRelList); - } - map.addAttribute("tenant", tenantRes.findById(id)); - return request(super.createRequestPageTempletResponse("/apps/tenant/edit")); - } - - @RequestMapping("/update") - @Menu(type = "apps", subtype = "tenant", admin = true) - public ModelAndView update(HttpServletRequest request, @Valid Tenant tenant, @RequestParam(value = "tenantpic", required = false) MultipartFile tenantpic, @Valid String skills) throws NoSuchAlgorithmException, IOException { - Tenant temp = tenantRes.findById(tenant.getId()); - Tenant tenanttemp = tenantRes.findByOrgidAndTenantname(super.getOrgid(request), tenant.getTenantname()); - if (temp != null && tenanttemp != null && !temp.getId().equals(tenanttemp.getId())) { - return request(super.createRequestPageTempletResponse("redirect:/apps/tenant/index.html?msg=tenantexist")); - } - if (tenant != null) { - tenant.setCreatetime(temp.getCreatetime()); - if (tenantpic != null && tenantpic.getOriginalFilename().lastIndexOf(".") > 0) { - File logoDir = new File(path, "tenantpic"); - if (!logoDir.exists()) { - logoDir.mkdirs(); - } - String fileName = "tenantpic/" + tenant.getId() + tenantpic.getOriginalFilename().substring( - tenantpic.getOriginalFilename().lastIndexOf(".")); - FileCopyUtils.copy(tenantpic.getBytes(), new File(path, fileName)); - tenant.setTenantlogo(fileName); - } else { - tenant.setTenantlogo(temp.getTenantlogo()); - } - if (!StringUtils.isBlank(super.getUser(request).getOrgid())) { - tenant.setOrgid(super.getUser(request).getOrgid()); - } else { - tenant.setOrgid(MainContext.SYSTEM_ORGI); - } - tenantRes.save(tenant); - List orgiSkillRelList = orgiSkillRelRes.findByOrgi(tenant.getId()); - orgiSkillRelRes.delete(orgiSkillRelList); - if (!StringUtils.isBlank(skills)) { - String[] skillsarray = skills.split(","); - for (String skill : skillsarray) { - OrgiSkillRel rel = new OrgiSkillRel(); - rel.setOrgi(tenant.getId()); - rel.setSkillid(skill); - rel.setCreater(super.getUser(request).getId()); - rel.setCreatetime(new Date()); - orgiSkillRelRes.save(rel); - } - } - OnlineUserProxy.clean(tenant.getId()); - } - return request(super.createRequestPageTempletResponse("redirect:/apps/tenant/index")); - } - - @RequestMapping("/delete") - @Menu(type = "apps", subtype = "tenant") - public ModelAndView delete(HttpServletRequest request, @Valid Tenant tenant) { - Tenant temp = tenantRes.findById(tenant.getId()); - if (tenant != null) { - tenantRes.delete(temp); - } - return request(super.createRequestPageTempletResponse("redirect:/apps/tenant/index")); - } - - @RequestMapping("/canswitch") - @Menu(type = "apps", subtype = "tenant") - public ModelAndView canswitch(HttpServletRequest request, @Valid Tenant tenant) throws UnsupportedEncodingException { - ModelAndView view = request(super.createRequestPageTempletResponse("redirect:/")); - AgentStatus agentStatus = cache.findOneAgentStatusByAgentnoAndOrig( - (super.getUser(request)).getId(), super.getOrgi(request)); - if (agentStatus == null && cache.getInservAgentUsersSizeByAgentnoAndOrgi( - super.getUser(request).getId(), super.getOrgi(request)) == 0) { - Tenant temp = tenantRes.findById(tenant.getId()); - if (temp != null) { - super.getUser(request).setOrgi(temp.getId()); - } - return view; - } - if (agentStatus != null) { - if (tenant.getId().equals(agentStatus.getOrgi())) { - Tenant temp = tenantRes.findById(tenant.getId()); - if (temp != null) { - super.getUser(request).setOrgi(temp.getId()); - } - return view; - } else { - Tenant temp = tenantRes.findById(agentStatus.getOrgi()); - return request(super.createRequestPageTempletResponse( - "redirect:/apps/tenant/index.html?msg=t0" + "¤torgi=" + agentStatus.getOrgi() + "¤tname=" + URLEncoder.encode( - temp != null ? temp.getTenantname() : "", "UTF-8"))); - } - } - AgentUser agentUser = agentUserRepository.findOneByAgentnoAndStatusAndOrgi( - super.getUser(request).getId(), MainContext.AgentUserStatusEnum.INSERVICE.toString(), - super.getOrgi(request)); - if (agentUser != null) { - if (tenant.getId().equals(agentUser.getOrgi())) { - Tenant temp = tenantRes.findById(tenant.getId()); - if (temp != null) { - super.getUser(request).setOrgi(temp.getId()); - } - return view; - } else { - Tenant temp = tenantRes.findById(agentUser.getOrgi()); - return request(super.createRequestPageTempletResponse( - "redirect:/apps/tenant/index.html?msg=t0" + "¤torgi=" + agentUser.getOrgi() + "¤tname=" + URLEncoder.encode( - temp != null ? temp.getTenantname() : "", "UTF-8"))); - } - - } - return request(super.createRequestPageTempletResponse("redirect:/apps/tenant/index.html?msg=t0")); - } -} +/* + * Copyright (C) 2017 优客服-多渠道客服系统 + * Modifications copyright (C) 2018-2019 Chatopera Inc, + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.chatopera.cc.controller.apps; + +import com.chatopera.cc.basic.MainContext; +import com.chatopera.cc.cache.Cache; +import com.chatopera.cc.controller.Handler; +import com.chatopera.cc.model.*; +import com.chatopera.cc.persistence.repository.*; +import com.chatopera.cc.proxy.OnlineUserProxy; +import com.chatopera.cc.util.Menu; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.lang.NonNull; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.util.FileCopyUtils; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +@Controller +@RequestMapping("/apps/tenant") +@RequiredArgsConstructor +public class TenantController extends Handler { + + @NonNull + private final TenantRepository tenantRes; + + @NonNull + private final OrgiSkillRelRepository orgiSkillRelRes; + + @NonNull + private final OrganRepository organRes; + + @NonNull + private final OrganizationRepository organizationRes; + + @NonNull + private final AgentUserRepository agentUserRepository; + + @NonNull + private final Cache cache; + + @Value("${web.upload-path}") + private String path; + + @RequestMapping("/index") + @Menu(type = "apps", subtype = "tenant") + public ModelAndView index( + ModelMap map, final HttpServletRequest request, + final @Valid String msg, + final @Valid String currentorgi, + final @Valid String currentname) throws IOException { + if (super.isEnabletneant()) { + // 系统管理员开启多租户访问 + if (super.getUser(request).isAdmin()) { + map.addAttribute("tenantList", tenantRes.findByOrgid(super.getOrgid(request))); + } else { + List orgiSkillRelList = orgiSkillRelRes.findBySkillidIn( + new ArrayList<>((super.getUser(request)).getAffiliates())); + List tenantList = null; + if (!orgiSkillRelList.isEmpty()) { + tenantList = new ArrayList<>(); + for (OrgiSkillRel orgiSkillRel : orgiSkillRelList) { + Tenant t = tenantRes.findById(orgiSkillRel.getOrgi()); + if (t != null) { + tenantList.add(t); + } + } + } + map.addAttribute("tenantList", tenantList); + } + } else { + map.addAttribute("tenantList", tenantRes.findById(super.getOrgi(request))); + } + map.addAttribute("organization", organizationRes.findById(super.getUser(request).getOrgid())); + map.addAttribute("msg", msg); + map.addAttribute("currentorgi", currentorgi); + if (currentname != null) { + map.addAttribute("currentname", URLDecoder.decode(currentname, "UTF-8")); + } + return request(super.createRequestPageTempletResponse("/apps/tenant/index")); + } + + @RequestMapping("/add") + @Menu(type = "apps", subtype = "tenant") + public ModelAndView add(ModelMap map, HttpServletRequest request) { + if (super.isTenantshare()) { + map.addAttribute("isShowSkillGroups", true); + List organList = organRes.findByOrgiAndOrgid( + super.getOrgiByTenantshare(request), super.getOrgid(request)); + map.addAttribute("skillGroups", organList); + } + return request(super.createRequestPageTempletResponse("/apps/tenant/add")); + } + + @RequestMapping("/save") + @Menu(type = "apps", subtype = "tenant") + public ModelAndView save(HttpServletRequest request, @Valid Tenant tenant, @RequestParam(value = "tenantpic", required = false) MultipartFile tenantpic, @Valid String skills) throws IOException { + Tenant tenanttemp = tenantRes.findByOrgidAndTenantname(super.getOrgid(request), tenant.getTenantname()); + if (tenanttemp != null) { + return request(super.createRequestPageTempletResponse("redirect:/apps/tenant/index.html?msg=tenantexist")); + } + tenantRes.save(tenant); + if (tenantpic != null && tenantpic.getOriginalFilename() != null && tenantpic.getOriginalFilename().lastIndexOf(".") > 0) { + File logoDir = new File(path, "tenantpic"); + if (!logoDir.exists()) { + //noinspection ResultOfMethodCallIgnored + logoDir.mkdirs(); + } + String fileName = "tenantpic/" + tenant.getId() + tenantpic.getOriginalFilename().substring( + tenantpic.getOriginalFilename().lastIndexOf(".")); + FileCopyUtils.copy(tenantpic.getBytes(), new File(path, fileName)); + tenant.setTenantlogo(fileName); + } + String tenantid = tenant.getId(); + List orgiSkillRelList = orgiSkillRelRes.findByOrgi(tenantid); + orgiSkillRelRes.deleteAll(orgiSkillRelList); + if (!StringUtils.isBlank(skills)) { + String[] skillsarray = skills.split(","); + for (String skill : skillsarray) { + OrgiSkillRel rel = new OrgiSkillRel(); + rel.setOrgi(tenant.getId()); + rel.setSkillid(skill); + rel.setCreater(super.getUser(request).getId()); + rel.setCreatetime(new Date()); + orgiSkillRelRes.save(rel); + } + } + if (!StringUtils.isBlank(super.getUser(request).getOrgid())) { + tenant.setOrgid(super.getUser(request).getOrgid()); + } else { + tenant.setOrgid(MainContext.SYSTEM_ORGI); + } + tenantRes.save(tenant); + OnlineUserProxy.clean(tenantid); + return request(super.createRequestPageTempletResponse("redirect:/apps/tenant/index")); + } + + @RequestMapping("/edit") + @Menu(type = "apps", subtype = "tenant") + public ModelAndView edit(ModelMap map, HttpServletRequest request, @Valid String id) { + if (super.isTenantshare()) { + map.addAttribute("isShowSkillGroups", true); + List organList = organRes.findByOrgiAndOrgid( + super.getOrgiByTenantshare(request), super.getOrgid(request)); + map.addAttribute("skillGroups", organList); + List orgiSkillRelList = orgiSkillRelRes.findByOrgi(id); + map.addAttribute("orgiSkillRelList", orgiSkillRelList); + } + map.addAttribute("tenant", tenantRes.findById(id)); + return request(super.createRequestPageTempletResponse("/apps/tenant/edit")); + } + + @RequestMapping("/update") + @Menu(type = "apps", subtype = "tenant", admin = true) + public ModelAndView update(HttpServletRequest request, @NonNull @Valid Tenant tenant, @RequestParam(value = "tenantpic", required = false) MultipartFile tenantpic, @Valid String skills) throws IOException { + Tenant temp = tenantRes.findById(tenant.getId()); + Tenant tenanttemp = tenantRes.findByOrgidAndTenantname(super.getOrgid(request), tenant.getTenantname()); + if (temp != null && tenanttemp != null && !temp.getId().equals(tenanttemp.getId())) { + return request(super.createRequestPageTempletResponse("redirect:/apps/tenant/index.html?msg=tenantexist")); + } + tenant.setCreatetime(temp.getCreatetime()); + if (tenantpic != null && tenantpic.getOriginalFilename() != null && tenantpic.getOriginalFilename().lastIndexOf(".") > 0) { + File logoDir = new File(path, "tenantpic"); + if (!logoDir.exists()) { + //noinspection ResultOfMethodCallIgnored + logoDir.mkdirs(); + } + String fileName = "tenantpic/" + tenant.getId() + tenantpic.getOriginalFilename().substring( + tenantpic.getOriginalFilename().lastIndexOf(".")); + FileCopyUtils.copy(tenantpic.getBytes(), new File(path, fileName)); + tenant.setTenantlogo(fileName); + } else { + tenant.setTenantlogo(temp.getTenantlogo()); + } + if (!StringUtils.isBlank(super.getUser(request).getOrgid())) { + tenant.setOrgid(super.getUser(request).getOrgid()); + } else { + tenant.setOrgid(MainContext.SYSTEM_ORGI); + } + tenantRes.save(tenant); + List orgiSkillRelList = orgiSkillRelRes.findByOrgi(tenant.getId()); + orgiSkillRelRes.deleteAll(orgiSkillRelList); + if (!StringUtils.isBlank(skills)) { + String[] skillsarray = skills.split(","); + for (String skill : skillsarray) { + OrgiSkillRel rel = new OrgiSkillRel(); + rel.setOrgi(tenant.getId()); + rel.setSkillid(skill); + rel.setCreater(super.getUser(request).getId()); + rel.setCreatetime(new Date()); + orgiSkillRelRes.save(rel); + } + } + OnlineUserProxy.clean(tenant.getId()); + return request(super.createRequestPageTempletResponse("redirect:/apps/tenant/index")); + } + + @RequestMapping("/delete") + @Menu(type = "apps", subtype = "tenant") + public ModelAndView delete(@Valid Tenant tenant) { + Tenant temp = tenantRes.findById(tenant.getId()); + if (tenant != null) { + tenantRes.delete(temp); + } + return request(super.createRequestPageTempletResponse("redirect:/apps/tenant/index")); + } + + @RequestMapping("/canswitch") + @Menu(type = "apps", subtype = "tenant") + public ModelAndView canswitch(HttpServletRequest request, @Valid Tenant tenant) throws UnsupportedEncodingException { + ModelAndView view = request(super.createRequestPageTempletResponse("redirect:/")); + AgentStatus agentStatus = cache.findOneAgentStatusByAgentnoAndOrig( + (super.getUser(request)).getId(), super.getOrgi(request)); + if (agentStatus == null && cache.getInservAgentUsersSizeByAgentnoAndOrgi( + super.getUser(request).getId(), super.getOrgi(request)) == 0) { + Tenant temp = tenantRes.findById(tenant.getId()); + if (temp != null) { + super.getUser(request).setOrgi(temp.getId()); + } + return view; + } + if (agentStatus != null) { + if (tenant.getId().equals(agentStatus.getOrgi())) { + Tenant temp = tenantRes.findById(tenant.getId()); + if (temp != null) { + super.getUser(request).setOrgi(temp.getId()); + } + return view; + } else { + Tenant temp = tenantRes.findById(agentStatus.getOrgi()); + return request(super.createRequestPageTempletResponse( + "redirect:/apps/tenant/index.html?msg=t0" + "¤torgi=" + agentStatus.getOrgi() + "¤tname=" + URLEncoder.encode( + temp != null ? temp.getTenantname() : "", "UTF-8"))); + } + } + AgentUser agentUser = agentUserRepository.findOneByAgentnoAndStatusAndOrgi( + super.getUser(request).getId(), MainContext.AgentUserStatusEnum.INSERVICE.toString(), + super.getOrgi(request)); + if (agentUser != null) { + if (tenant.getId().equals(agentUser.getOrgi())) { + Tenant temp = tenantRes.findById(tenant.getId()); + if (temp != null) { + super.getUser(request).setOrgi(temp.getId()); + } + return view; + } else { + Tenant temp = tenantRes.findById(agentUser.getOrgi()); + return request(super.createRequestPageTempletResponse( + "redirect:/apps/tenant/index.html?msg=t0" + "¤torgi=" + agentUser.getOrgi() + "¤tname=" + URLEncoder.encode( + temp != null ? temp.getTenantname() : "", "UTF-8"))); + } + + } + return request(super.createRequestPageTempletResponse("redirect:/apps/tenant/index.html?msg=t0")); + } +} diff --git a/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/service/ChatServiceController.java b/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/service/ChatServiceController.java index 0ae812a2..68f5879f 100644 --- a/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/service/ChatServiceController.java +++ b/contact-center/app/src/main/java/com/chatopera/cc/controller/apps/service/ChatServiceController.java @@ -32,127 +32,124 @@ import com.chatopera.cc.socketio.message.Message; import com.chatopera.cc.util.IP; import com.chatopera.cc.util.IPTools; import com.chatopera.cc.util.Menu; +import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort.Direction; import org.springframework.data.jpa.domain.Specification; +import org.springframework.http.HttpStatus; +import org.springframework.lang.NonNull; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.server.ResponseStatusException; import org.springframework.web.servlet.ModelAndView; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; -import java.nio.charset.CharacterCodingException; import java.text.ParseException; import java.util.*; @Controller @RequestMapping("/service") +@RequiredArgsConstructor public class ChatServiceController extends Handler { private final static Logger logger = LoggerFactory.getLogger(ChatServiceController.class); - @Autowired - private AgentUserProxy agentUserProxy; + @NonNull + private final AgentUserProxy agentUserProxy; - @Autowired - private AgentStatusProxy agentStatusProxy; + @NonNull + private final AgentStatusProxy agentStatusProxy; - @Autowired - private ACDAgentService acdAgentService; + @NonNull + private final ACDAgentService acdAgentService; - @Autowired - private ACDVisitorDispatcher acdVisitorDispatcher; + @NonNull + private final ACDVisitorDispatcher acdVisitorDispatcher; - @Autowired - private AgentServiceRepository agentServiceRes; + @NonNull + private final AgentServiceRepository agentServiceRes; - @Autowired - private AgentUserRepository agentUserRes; + @NonNull + private final AgentUserRepository agentUserRes; - @Autowired - private AgentStatusRepository agentStatusRepository; + @NonNull + private final AgentStatusRepository agentStatusRepository; - @Autowired - private AgentUserRepository agentUserRepository; + @NonNull + private final AgentUserRepository agentUserRepository; - @Autowired - private LeaveMsgRepository leaveMsgRes; + @NonNull + private final LeaveMsgRepository leaveMsgRes; - @Autowired - private LeaveMsgProxy leaveMsgProxy; + @NonNull + private final LeaveMsgProxy leaveMsgProxy; - @Autowired - private OrganRepository organRes; + @NonNull + private final OrganRepository organRes; - @Autowired - private OrganRepository organ; + @NonNull + private final OrganRepository organ; - @Autowired - private UserRepository user; + @NonNull + private final UserRepository user; - @Autowired - private UserRepository userRes; + @NonNull + private final UserRepository userRes; - @Autowired - private OrgiSkillRelRepository orgiSkillRelService; + @NonNull + private final OrgiSkillRelRepository orgiSkillRelService; - @Autowired - private UserProxy userProxy; + @NonNull + private final UserProxy userProxy; - @Autowired - private Cache cache; + @NonNull + private final Cache cache; - @Autowired - private PeerSyncIM peerSyncIM; + @NonNull + private final PeerSyncIM peerSyncIM; - @Autowired - private ACDMessageHelper acdMessageHelper; + @NonNull + private final ACDMessageHelper acdMessageHelper; @RequestMapping("/history/index") @Menu(type = "service", subtype = "history", admin = true) public ModelAndView index(ModelMap map, HttpServletRequest request, final String username, final String channel, final String servicetype, final String allocation, final String servicetimetype, final String begin, final String end) { - Page page = agentServiceRes.findAll(new Specification() { - @Override - public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) { - List list = new ArrayList(); - if (StringUtils.isNotBlank(username)) { - list.add(cb.equal(root.get("username").as(String.class), username)); - } - if (StringUtils.isNotBlank(channel)) { - list.add(cb.equal(root.get("channel").as(String.class), channel)); - } - if (StringUtils.isNotBlank(servicetype) && StringUtils.isNotBlank(allocation)) { - list.add(cb.equal(root.get(servicetype).as(String.class), allocation)); - } - if (StringUtils.isNotBlank(servicetimetype)) { - try { - if (StringUtils.isNotBlank(begin) && begin.matches("[\\d]{4}-[\\d]{2}-[\\d]{2}")) { - list.add(cb.greaterThanOrEqualTo( - root.get(servicetimetype).as(Date.class), - MainUtils.simpleDateFormat.parse(begin))); - } - if (StringUtils.isNotBlank(end) && end.matches("[\\d]{4}-[\\d]{2}-[\\d]{2}")) { - list.add(cb.lessThanOrEqualTo( - root.get(servicetimetype).as(Date.class), - MainUtils.dateFormate.parse(end + " 23:59:59"))); - } - } catch (ParseException e) { - e.printStackTrace(); - } - } - Predicate[] p = new Predicate[list.size()]; - return cb.and(list.toArray(p)); + Page page = agentServiceRes.findAll((Specification) (root, query, cb) -> { + List list = new ArrayList<>(); + if (StringUtils.isNotBlank(username)) { + list.add(cb.equal(root.get("username").as(String.class), username)); } + if (StringUtils.isNotBlank(channel)) { + list.add(cb.equal(root.get("channel").as(String.class), channel)); + } + if (StringUtils.isNotBlank(servicetype) && StringUtils.isNotBlank(allocation)) { + list.add(cb.equal(root.get(servicetype).as(String.class), allocation)); + } + if (StringUtils.isNotBlank(servicetimetype)) { + try { + if (StringUtils.isNotBlank(begin) && begin.matches("[\\d]{4}-[\\d]{2}-[\\d]{2}")) { + list.add(cb.greaterThanOrEqualTo( + root.get(servicetimetype).as(Date.class), + MainUtils.simpleDateFormat.parse(begin))); + } + if (StringUtils.isNotBlank(end) && end.matches("[\\d]{4}-[\\d]{2}-[\\d]{2}")) { + list.add(cb.lessThanOrEqualTo( + root.get(servicetimetype).as(Date.class), + MainUtils.dateFormate.parse(end + " 23:59:59"))); + } + } catch (ParseException e) { + e.printStackTrace(); + } + } + Predicate[] p = new Predicate[list.size()]; + return cb.and(list.toArray(p)); }, PageRequest.of(super.getP(request), super.getPs(request), Direction.DESC, "createtime")); map.put("agentServiceList", page); map.put("username", username); @@ -199,7 +196,7 @@ public class ChatServiceController extends Handler { } } List agentStatusList = cache.getAgentStatusBySkillAndOrgi(null, super.getOrgi(request)); - List usersids = new ArrayList(); + List usersids = new ArrayList<>(); if (!agentStatusList.isEmpty()) { for (AgentStatus agentStatus : agentStatusList) { if (agentStatus != null) { @@ -207,16 +204,18 @@ public class ChatServiceController extends Handler { } } } - List userList = userRes.findAll(usersids); + List userList = userRes.findAllById(usersids); for (User user : userList) { user.setAgentStatus(cache.findOneAgentStatusByAgentnoAndOrig(user.getId(), super.getOrgi(request))); userProxy.attachOrgansPropertiesForUser(user); } map.addAttribute("userList", userList); - map.addAttribute("userid", agentService.getUserid()); - map.addAttribute("agentserviceid", agentService.getId()); - map.addAttribute("agentuserid", agentService.getAgentuserid()); - map.addAttribute("agentservice", agentService); + if (agentService != null) { + map.addAttribute("userid", agentService.getUserid()); + map.addAttribute("agentserviceid", agentService.getId()); + map.addAttribute("agentuserid", agentService.getAgentuserid()); + map.addAttribute("agentservice", agentService); + } map.addAttribute("skillGroups", skillGroups); map.addAttribute("currentorgan", currentOrgan); } @@ -226,10 +225,11 @@ public class ChatServiceController extends Handler { @RequestMapping(value = "/transfer/save") @Menu(type = "apps", subtype = "transfersave") - public ModelAndView transfersave(ModelMap map, HttpServletRequest request, @Valid String id, @Valid String agentno, @Valid String memo) throws CharacterCodingException { + public ModelAndView transfersave(HttpServletRequest request, @Valid String id, @Valid String agentno, @Valid String memo) { if (StringUtils.isNotBlank(id)) { - AgentService agentService = agentServiceRes.findByIdAndOrgi(id, super.getOrgi(request)); - final User targetAgent = userRes.findOne(agentno); + AgentService agentService = Objects.requireNonNull(agentServiceRes.findByIdAndOrgi(id, super.getOrgi(request))); + final User targetAgent = userRes.findById(agentno) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, String.format("Agent %s not found", agentno))); AgentUser agentUser = null; Optional agentUserOpt = cache.findOneAgentUserByUserIdAndOrgi( agentService.getUserid(), super.getOrgi(request)); @@ -303,15 +303,13 @@ public class ChatServiceController extends Handler { } } - if (agentService != null) { - agentService.setAgentno(agentno); - if (StringUtils.isNotBlank(memo)) { - agentService.setTransmemo(memo); - } - agentService.setTrans(true); - agentService.setTranstime(new Date()); - agentServiceRes.save(agentService); + agentService.setAgentno(agentno); + if (StringUtils.isNotBlank(memo)) { + agentService.setTransmemo(memo); } + agentService.setTrans(true); + agentService.setTranstime(new Date()); + agentServiceRes.save(agentService); } return request(super.createRequestPageTempletResponse("redirect:/service/current/index.html")); @@ -319,7 +317,7 @@ public class ChatServiceController extends Handler { @RequestMapping("/current/end") @Menu(type = "service", subtype = "current", admin = true) - public ModelAndView end(ModelMap map, HttpServletRequest request, @Valid String id) throws Exception { + public ModelAndView end(HttpServletRequest request, @Valid String id) throws Exception { if (StringUtils.isNotBlank(id)) { AgentService agentService = agentServiceRes.findByIdAndOrgi(id, super.getOrgi(request)); if (agentService != null) { @@ -338,19 +336,12 @@ public class ChatServiceController extends Handler { /** * 邀请 - * - * @param map - * @param request - * @param id - * @return - * @throws Exception */ @RequestMapping("/current/invite") @Menu(type = "service", subtype = "current", admin = true) public ModelAndView currentinvite( - ModelMap map, final HttpServletRequest request, - final @Valid String id) throws Exception { + final @Valid String id) { if (StringUtils.isNotBlank(id)) { AgentService agentService = agentServiceRes.findByIdAndOrgi(id, super.getOrgi(request)); if (agentService != null) { @@ -402,7 +393,7 @@ public class ChatServiceController extends Handler { Page agentUserList = agentUserRes.findByOrgiAndStatus( super.getOrgi(request), MainContext.AgentUserStatusEnum.INQUENE.toString(), PageRequest.of(super.getP(request), super.getPs(request), Direction.DESC, "createtime")); - List skillGroups = new ArrayList(); + List skillGroups = new ArrayList<>(); for (AgentUser agentUser : agentUserList.getContent()) { agentUser.setWaittingtime((int) (System.currentTimeMillis() - agentUser.getCreatetime().getTime())); if (StringUtils.isNotBlank(agentUser.getSkill())) { @@ -410,7 +401,7 @@ public class ChatServiceController extends Handler { } } if (skillGroups.size() > 0) { - List organList = organRes.findAll(skillGroups); + List organList = organRes.findAllById(skillGroups); for (AgentUser agentUser : agentUserList.getContent()) { if (StringUtils.isNotBlank(agentUser.getSkill())) { for (Organ organ : organList) { @@ -428,7 +419,7 @@ public class ChatServiceController extends Handler { @RequestMapping("/quene/clean") @Menu(type = "service", subtype = "queneclean", admin = true) - public ModelAndView clean(ModelMap map, HttpServletRequest request, @Valid String id) { + public ModelAndView clean(HttpServletRequest request, @Valid String id) { AgentUser agentUser = agentUserRes.findByIdAndOrgi(id, super.getOrgi(request)); if (agentUser != null && agentUser.getStatus().equals(MainContext.AgentUserStatusEnum.INQUENE.toString())) { agentUser.setAgentno(null); @@ -443,7 +434,7 @@ public class ChatServiceController extends Handler { @RequestMapping("/quene/invite") @Menu(type = "service", subtype = "invite", admin = true) - public ModelAndView invite(ModelMap map, HttpServletRequest request, @Valid String id) throws Exception { + public ModelAndView invite(HttpServletRequest request, @Valid String id) { final User logined = super.getUser(request); final String orgi = logined.getOrgi(); AgentUser agentUser = agentUserRes.findByIdAndOrgi(id, super.getOrgi(request)); @@ -455,10 +446,6 @@ public class ChatServiceController extends Handler { /** * 管理员查看在线坐席 - * - * @param map - * @param request - * @return */ @RequestMapping("/agent/index") @Menu(type = "service", subtype = "onlineagent", admin = true) @@ -476,21 +463,16 @@ public class ChatServiceController extends Handler { /** * 查看离线坐席 - * - * @param map - * @param request - * @param id - * @return */ @RequestMapping("/agent/offline") @Menu(type = "service", subtype = "offline", admin = true) - public ModelAndView offline(ModelMap map, HttpServletRequest request, @Valid String id) { + public ModelAndView offline(HttpServletRequest request, @Valid String id) { AgentStatus agentStatus = agentStatusRepository.findByIdAndOrgi(id, super.getOrgi(request)); if (agentStatus != null) { agentStatusRepository.delete(agentStatus); + cache.deleteAgentStatusByAgentnoAndOrgi(agentStatus.getAgentno(), super.getOrgi(request)); } - cache.deleteAgentStatusByAgentnoAndOrgi(agentStatus.getAgentno(), super.getOrgi(request)); agentStatusProxy.broadcastAgentsStatus( super.getOrgi(request), "agent", "offline", super.getUser(request).getId()); @@ -500,10 +482,6 @@ public class ChatServiceController extends Handler { /** * 非管理员坐席 - * - * @param map - * @param request - * @return */ @RequestMapping("/user/index") @Menu(type = "service", subtype = "userlist", admin = true) @@ -552,9 +530,9 @@ public class ChatServiceController extends Handler { @RequestMapping("/leavemsg/delete") @Menu(type = "service", subtype = "leavemsg", admin = true) - public ModelAndView leavemsg(ModelMap map, HttpServletRequest request, @Valid String id) { + public ModelAndView leavemsg(@Valid String id) { if (StringUtils.isNotBlank(id)) { - leaveMsgRes.delete(id); + leaveMsgRes.deleteById(id); } return request(super.createRequestPageTempletResponse("redirect:/service/leavemsg/index.html")); } diff --git a/contact-center/app/src/main/java/com/chatopera/cc/persistence/repository/AgentServiceRepository.java b/contact-center/app/src/main/java/com/chatopera/cc/persistence/repository/AgentServiceRepository.java index 8e76119c..74e49b6f 100644 --- a/contact-center/app/src/main/java/com/chatopera/cc/persistence/repository/AgentServiceRepository.java +++ b/contact-center/app/src/main/java/com/chatopera/cc/persistence/repository/AgentServiceRepository.java @@ -1,56 +1,56 @@ -/* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2019 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.chatopera.cc.persistence.repository; - -import com.chatopera.cc.model.AgentService; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; - -import java.util.List; -import java.util.Optional; - -public interface AgentServiceRepository - extends JpaRepository -{ - AgentService findByIdAndOrgi(String paramString, String orgi); - - List findByUseridAndOrgiOrderByLogindateDesc(String paramString, String orgi); - - @Query(value = "SELECT * FROM uk_agentservice WHERE userid= ?1 AND orgi = ?2 ORDER BY logindate DESC LIMIT 1", nativeQuery = true) - Optional findOneByUseridAndOrgiOrderByLogindateDesc(String userid, String orgi); - - AgentService findFirstByUserid(String userid); - - Page findByOrgi(String orgi, Pageable paramPageable); - - Page findByOrgiAndSatisfaction(String orgi, boolean satisfaction, Pageable paramPageable); - - Page findByOrgiAndStatus(String orgi, String status, Pageable paramPageable); - - List findByAgentnoAndStatusAndOrgi(String agentno, String status, String orgi); - - int countByUseridAndOrgiAndStatus(String userid, String orgi, String status); - - List findByUseridAndOrgiAndStatus(String userid, String orgi, String status, Sort sort); - - Page findAll(Specification spec, Pageable pageable); //分页按条件查询 - -} +/* + * Copyright (C) 2017 优客服-多渠道客服系统 + * Modifications copyright (C) 2018-2019 Chatopera Inc, + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.chatopera.cc.persistence.repository; + +import com.chatopera.cc.model.AgentService; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.lang.Nullable; + +import java.util.List; +import java.util.Optional; + +public interface AgentServiceRepository extends JpaRepository { + @Nullable + AgentService findByIdAndOrgi(String paramString, String orgi); + + List findByUseridAndOrgiOrderByLogindateDesc(String paramString, String orgi); + + @Query(value = "SELECT * FROM uk_agentservice WHERE userid= ?1 AND orgi = ?2 ORDER BY logindate DESC LIMIT 1", nativeQuery = true) + Optional findOneByUseridAndOrgiOrderByLogindateDesc(String userid, String orgi); + + AgentService findFirstByUserid(String userid); + + Page findByOrgi(String orgi, Pageable paramPageable); + + Page findByOrgiAndSatisfaction(String orgi, boolean satisfaction, Pageable paramPageable); + + Page findByOrgiAndStatus(String orgi, String status, Pageable paramPageable); + + List findByAgentnoAndStatusAndOrgi(String agentno, String status, String orgi); + + int countByUseridAndOrgiAndStatus(String userid, String orgi, String status); + + List findByUseridAndOrgiAndStatus(String userid, String orgi, String status, Sort sort); + + Page findAll(Specification spec, Pageable pageable); //分页按条件查询 + +} diff --git a/contact-center/app/src/main/java/com/chatopera/cc/persistence/repository/AgentUserRepository.java b/contact-center/app/src/main/java/com/chatopera/cc/persistence/repository/AgentUserRepository.java index 2f006ed1..635058d2 100644 --- a/contact-center/app/src/main/java/com/chatopera/cc/persistence/repository/AgentUserRepository.java +++ b/contact-center/app/src/main/java/com/chatopera/cc/persistence/repository/AgentUserRepository.java @@ -1,88 +1,88 @@ -/* - * Copyright (C) 2017 优客服-多渠道客服系统 - * Modifications copyright (C) 2018-2019 Chatopera Inc, - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.chatopera.cc.persistence.repository; - -import com.chatopera.cc.model.AgentUser; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; - -import java.util.List; -import java.util.Optional; - -public interface AgentUserRepository extends JpaRepository { - AgentUser findByIdAndOrgi(String paramString, String orgi); - - @Query(value = "SELECT * FROM uk_agentuser WHERE userid = ?1 AND orgi = ?2 ORDER BY createtime DESC LIMIT 1", nativeQuery = true) - Optional findOneByUseridAndOrgi(String userid, String orgi); - - @Query(value = "SELECT * FROM uk_agentuser WHERE userid = ?1 LIMIT 1", nativeQuery = true) - AgentUser findOneByUserid(final String userid); - - List findByUseridAndOrgi(String userid, String orgi); - - List findByUseridAndStatus(String userid, String status); - - List findByAgentnoAndOrgi(String agentno, String orgi, Sort sort); - - List findByAgentnoAndOrgi(String agentno, String orgi); - - Page findByOrgiAndStatus(String orgi, String status, Pageable page); - - List findByOrgiAndStatus(final String orgi, final String status, final Sort sort); - - List findByOrgiAndStatusAndAgentnoIsNot(final String orgi, final String status, final String agentno, final Sort sort); - - List findByOrgiAndStatusAndSkillAndAgentno(final String orgi, final String status, final String skill, final String agentno, Sort defaultSort); - - List findByAgentnoAndStatusAndOrgi(String agentno, String status, String orgi); - - List findByOrgiAndStatusAndSkillAndAgentnoIsNot(final String orgi, final String status, final String skill, final String agentno, final Sort sort); - - List findByOrgiAndStatusAndAgentno(final String orgi, final String status, final String agentno, final Sort defaultSort); - - @Query(value = "SELECT a FROM AgentUser a WHERE a.userid in(:userids)") - List findAllByUserids(@Param("userids") List userids); - - int countByAgentnoAndStatusAndOrgi(String agentno, String status, String orgi); - - AgentUser findOneByAgentnoAndStatusAndOrgi(String id, String status, String orgi); - - @Query(value = "SELECT * FROM uk_agentuser AS u " + - "LEFT JOIN uk_agentuser_contacts AS c " + - "ON u.userid = c.userid WHERE c.id = ?1 AND NOT u.status = ?2 AND c.orgi = ?3 LIMIT 1", nativeQuery = true) - AgentUser findOneByContactIdAndStatusNotAndOrgi(final String contactid, final String status, final String orgi); - - @Query(value = "SELECT * FROM uk_agentuser AS u " + - "LEFT JOIN uk_agentuser_contacts AS c " + - "ON u.userid = c.userid WHERE c.contactsid = ?1 " + - "AND c.channel = ?3 AND NOT u.status = ?2 AND c.orgi = ?4 " + - "ORDER BY u.createtime DESC LIMIT 1", nativeQuery = true) - Optional findOneByContactIdAndStatusNotAndChannelAndOrgi(final String contactid, final String status, final String channel, final String orgi); - - @Query(value = "SELECT * FROM uk_agentuser AS u " + - "LEFT JOIN uk_agentuser_contacts AS c " + - "ON u.userid = c.userid WHERE c.contactsid = ?1 " + - "AND c.channel = ?2 AND c.orgi = ?3 " + - "ORDER BY u.createtime DESC LIMIT 1", nativeQuery = true) - Optional findOneByContactIdAndChannelAndOrgi(final String contactid, final String channel, final String orgi); - - -} +/* + * Copyright (C) 2017 优客服-多渠道客服系统 + * Modifications copyright (C) 2018-2019 Chatopera Inc, + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.chatopera.cc.persistence.repository; + +import com.chatopera.cc.model.AgentUser; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; +import java.util.Optional; + +public interface AgentUserRepository extends JpaRepository { + AgentUser findByIdAndOrgi(String paramString, String orgi); + + @Query(value = "SELECT * FROM uk_agentuser WHERE userid = ?1 AND orgi = ?2 ORDER BY createtime DESC LIMIT 1", nativeQuery = true) + Optional findOneByUseridAndOrgi(String userid, String orgi); + + // @Query(value = "SELECT * FROM uk_agentuser WHERE userid = ?1 LIMIT 1", nativeQuery = true) + // AgentUser findOneByUserid(final String userid); + + List findByUseridAndOrgi(String userid, String orgi); + + // List findByUseridAndStatus(String userid, String status); + + List findByAgentnoAndOrgi(String agentno, String orgi, Sort sort); + + // List findByAgentnoAndOrgi(String agentno, String orgi); + + Page findByOrgiAndStatus(String orgi, String status, Pageable page); + + // List findByOrgiAndStatus(final String orgi, final String status, final Sort sort); + + List findByOrgiAndStatusAndAgentnoIsNot(final String orgi, final String status, final String agentno, final Sort sort); + + List findByOrgiAndStatusAndSkillAndAgentno(final String orgi, final String status, final String skill, final String agentno, Sort defaultSort); + + List findByAgentnoAndStatusAndOrgi(String agentno, String status, String orgi); + + List findByOrgiAndStatusAndSkillAndAgentnoIsNot(final String orgi, final String status, final String skill, final String agentno, final Sort sort); + + List findByOrgiAndStatusAndAgentno(final String orgi, final String status, final String agentno, final Sort defaultSort); + + @Query(value = "SELECT a FROM AgentUser a WHERE a.userid in(:userids)") + List findAllByUserids(@Param("userids") List userids); + + // int countByAgentnoAndStatusAndOrgi(String agentno, String status, String orgi); + + AgentUser findOneByAgentnoAndStatusAndOrgi(String id, String status, String orgi); + + @Query(value = "SELECT * FROM uk_agentuser AS u " + + "LEFT JOIN uk_agentuser_contacts AS c " + + "ON u.userid = c.userid WHERE c.id = ?1 AND NOT u.status = ?2 AND c.orgi = ?3 LIMIT 1", nativeQuery = true) + AgentUser findOneByContactIdAndStatusNotAndOrgi(final String contactid, final String status, final String orgi); + + @Query(value = "SELECT * FROM uk_agentuser AS u " + + "LEFT JOIN uk_agentuser_contacts AS c " + + "ON u.userid = c.userid WHERE c.contactsid = ?1 " + + "AND c.channel = ?3 AND NOT u.status = ?2 AND c.orgi = ?4 " + + "ORDER BY u.createtime DESC LIMIT 1", nativeQuery = true) + Optional findOneByContactIdAndStatusNotAndChannelAndOrgi(final String contactid, final String status, final String channel, final String orgi); + + @Query(value = "SELECT * FROM uk_agentuser AS u " + + "LEFT JOIN uk_agentuser_contacts AS c " + + "ON u.userid = c.userid WHERE c.contactsid = ?1 " + + "AND c.channel = ?2 AND c.orgi = ?3 " + + "ORDER BY u.createtime DESC LIMIT 1", nativeQuery = true) + Optional findOneByContactIdAndChannelAndOrgi(final String contactid, final String channel, final String orgi); + + +} diff --git a/contact-center/app/src/main/java/com/chatopera/cc/proxy/BlackEntityProxy.java b/contact-center/app/src/main/java/com/chatopera/cc/proxy/BlackEntityProxy.java index f25be2a8..57724aea 100644 --- a/contact-center/app/src/main/java/com/chatopera/cc/proxy/BlackEntityProxy.java +++ b/contact-center/app/src/main/java/com/chatopera/cc/proxy/BlackEntityProxy.java @@ -18,53 +18,40 @@ package com.chatopera.cc.proxy; import com.chatopera.cc.cache.Cache; import com.chatopera.cc.model.AgentService; -import com.chatopera.cc.model.AgentUser; import com.chatopera.cc.model.BlackEntity; import com.chatopera.cc.model.User; import com.chatopera.cc.persistence.repository.AgentServiceRepository; -import com.chatopera.cc.persistence.repository.AgentUserRepository; import com.chatopera.cc.persistence.repository.BlackListRepository; +import lombok.RequiredArgsConstructor; import org.apache.commons.lang.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.lang.NonNull; import org.springframework.stereotype.Component; -import javax.servlet.http.HttpServletRequest; import java.util.Date; @Component +@RequiredArgsConstructor public class BlackEntityProxy { - @Autowired - private BlackListRepository blackListRes; + @NonNull + private final BlackListRepository blackListRes; - @Autowired - private Cache cache; + @NonNull + private final Cache cache; - @Autowired - private AgentUserRepository agentUserRepository; - - @Autowired - private AgentServiceRepository agentServiceRes; + @NonNull + private final AgentServiceRepository agentServiceRes; /** * 更新或创建黑名单记录 - * - * @param pre - * @param owner - * @param userid - * @param orgi - * @param agentserviceid - * @param agentuserid - * @return */ - public BlackEntity updateOrCreateBlackEntity( + public void updateOrCreateBlackEntity( final BlackEntity pre, final User owner, final String userid, final String orgi, - final String agentserviceid, - final String agentuserid) { + final String agentserviceid) { final BlackEntity blackEntityUpdated = cache.findOneBlackEntityByUserIdAndOrgi( userid, orgi).orElseGet( () -> { @@ -102,6 +89,5 @@ public class BlackEntityProxy { blackListRes.save(blackEntityUpdated); - return blackEntityUpdated; } } diff --git a/contact-center/app/src/main/java/com/chatopera/cc/proxy/ContactsProxy.java b/contact-center/app/src/main/java/com/chatopera/cc/proxy/ContactsProxy.java index 84ec8d4d..98741512 100644 --- a/contact-center/app/src/main/java/com/chatopera/cc/proxy/ContactsProxy.java +++ b/contact-center/app/src/main/java/com/chatopera/cc/proxy/ContactsProxy.java @@ -22,12 +22,12 @@ import com.chatopera.cc.persistence.es.ContactsRepository; import com.chatopera.cc.persistence.repository.AgentUserRepository; import com.chatopera.cc.persistence.repository.OnlineUserRepository; import com.chatopera.cc.persistence.repository.SNSAccountRepository; +import lombok.RequiredArgsConstructor; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; +import org.springframework.lang.NonNull; import org.springframework.stereotype.Component; import org.springframework.ui.ModelMap; @@ -37,34 +37,27 @@ import java.util.*; * 向联系人发送消息 */ @Component +@RequiredArgsConstructor public class ContactsProxy { private final static Logger logger = LoggerFactory.getLogger(ContactsProxy.class); - @Autowired - private Cache cache; + @NonNull + private final Cache cache; - @Autowired - private AgentUserRepository agentUserRes; + @NonNull + private final AgentUserRepository agentUserRes; - @Autowired - private ContactsRepository contactsRes; - - @Autowired - private OnlineUserRepository onlineUserRes; - - @Value("${web.upload-path}") - private String path; - - @Autowired - private SNSAccountRepository snsAccountRes; + @NonNull + private final ContactsRepository contactsRes; + @NonNull + private final OnlineUserRepository onlineUserRes; + @NonNull + private final SNSAccountRepository snsAccountRes; /** * 在传输SkypeId中有操作混入了非法字符 - * - * @param dirty - * @return */ public String sanitizeSkypeId(final String dirty) { if (dirty != null) { @@ -80,7 +73,6 @@ public class ContactsProxy { * * @param logined 当前查询该信息的访客 * @param contactid 目标联系人ID - * @return */ public List liveApproachChannelsByContactid( final User logined, @@ -106,9 +98,7 @@ public class ContactsProxy { if (!cache.existBlackEntityByUserIdAndOrgi(p.getUserid(), logined.getOrgi())) { // 访客在线 WebIM,排队或服务中 result.add(MainContext.ChannelType.WEBIM); - } else { - // 该访客被拉黑 - } + } // else 该访客被拉黑 }); // 查看 Skype 渠道 @@ -162,10 +152,6 @@ public class ContactsProxy { /** * 批量查询联系人的可触达状态 - * - * @param contacts - * @param map - * @param user */ public void bindContactsApproachableData(final Page contacts, final ModelMap map, final User user) { Set approachable = new HashSet<>(); @@ -184,23 +170,14 @@ public class ContactsProxy { /** * 检查Skype渠道是否被建立 - * - * @return */ public boolean isSkypeSetup(final String orgi) { - if (MainContext.hasModule(Constants.CSKEFU_MODULE_SKYPE) && snsAccountRes.countBySnstypeAndOrgi( - Constants.CSKEFU_MODULE_SKYPE, orgi) > 0) { - return true; - } - return false; + return MainContext.hasModule(Constants.CSKEFU_MODULE_SKYPE) && snsAccountRes.countBySnstypeAndOrgi( + Constants.CSKEFU_MODULE_SKYPE, orgi) > 0; } /** * 判断编辑是否变更 - * - * @param newValue - * @param oldValue - * @return */ public boolean determineChange(Contacts newValue, Contacts oldValue) { return (!newValue.getName().equals(oldValue.getName()) ||