|
|
@@ -68,6 +68,17 @@ import java.util.stream.Collectors;
|
|
|
@Service
|
|
|
@Slf4j
|
|
|
public class OpenIMServiceImpl implements OpenIMService {
|
|
|
+ /** IM账号注册状态缓存key前缀,已注册=1,缓存5分钟 */
|
|
|
+ private static final String IM_ACCOUNT_REGISTERED_KEY = "im:account:registered:";
|
|
|
+ /** IM账号注册状态缓存时间(秒) */
|
|
|
+ private static final int IM_ACCOUNT_CACHE_SECONDS = 300;
|
|
|
+ /** IM好友关系缓存key前缀 */
|
|
|
+ private static final String IM_FRIEND_STATUS_KEY = "im:friend:status:";
|
|
|
+ /** IM好友关系缓存时间(秒) */
|
|
|
+ private static final int IM_FRIEND_CACHE_SECONDS = 300;
|
|
|
+ /** HTTP请求超时时间(毫秒) */
|
|
|
+ private static final int HTTP_TIMEOUT_MS = 10000;
|
|
|
+
|
|
|
@Autowired
|
|
|
IMConfig imConfig;
|
|
|
@Autowired
|
|
|
@@ -104,6 +115,20 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
@Autowired
|
|
|
private FsCourseWatchLogMapper fsCourseWatchLogMapper;
|
|
|
|
|
|
+ /**
|
|
|
+ * 通用IM HTTP POST请求封装,统一超时和header设置
|
|
|
+ */
|
|
|
+ private String imPost(String path, String bodyJson) {
|
|
|
+ String adminToken = getAdminToken();
|
|
|
+ return HttpRequest.post(IMConfig.URL + path)
|
|
|
+ .header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
+ .header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
+ .body(bodyJson)
|
|
|
+ .execute()
|
|
|
+ .body();
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
// @Value("${openIM.prefix}")
|
|
|
// private String openImPrefix;
|
|
|
@@ -123,6 +148,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
try {
|
|
|
String response = HttpRequest.post(IMConfig.URL+"/auth/get_admin_token")
|
|
|
.header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
.body(requestBody.toString())
|
|
|
.execute()
|
|
|
.body();
|
|
|
@@ -229,7 +255,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
openImConversationDTO.setUserID(sendID);
|
|
|
openImEditConversationDTO.setConversation(openImConversationDTO);
|
|
|
OpenImResponseDTO openImResponseDTO1 = editConversation(openImEditConversationDTO);
|
|
|
- log.info("修改回话返回参数:{}", openImResponseDTO1);
|
|
|
+ log.debug("修改回话返回参数:{}", openImResponseDTO1);
|
|
|
}
|
|
|
return null;
|
|
|
} catch (Exception e) {
|
|
|
@@ -277,7 +303,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
}
|
|
|
currentConversation.setConversation(openImConversationDTO);
|
|
|
OpenImResponseDTO openImResponseDTO1 = editConversation(currentConversation);
|
|
|
- log.info("修改回话返回参数:{}", openImResponseDTO1);
|
|
|
+ log.debug("修改回话返回参数:{}", openImResponseDTO1);
|
|
|
return true;
|
|
|
}
|
|
|
//③正常i情况 直接返回
|
|
|
@@ -289,53 +315,87 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
}
|
|
|
|
|
|
private String getIMList( String recvID,String conversationId) {
|
|
|
- int pageNumber = 1;
|
|
|
- int pageSize = 20;
|
|
|
- int maxPages = 10; // 最大搜索页数,防止无限循环
|
|
|
+ // 优化:直接查询指定会话,而非分页遍历全部会话
|
|
|
String adminToken = getAdminToken();
|
|
|
try {
|
|
|
- while (pageNumber <= maxPages) {
|
|
|
- JSONObject requestBody = new JSONObject();
|
|
|
- requestBody.put("userID", recvID);
|
|
|
- JSONObject pagination = new JSONObject();
|
|
|
- pagination.put("pageNumber", pageNumber);
|
|
|
- pagination.put("showNumber", pageSize);
|
|
|
- requestBody.put("pagination", pagination);
|
|
|
- String body = HttpRequest.post("https://webim.zkhj6.com/api/conversation/get_owner_conversation")
|
|
|
- .header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
- .header("token", adminToken)
|
|
|
- .body(requestBody.toString())
|
|
|
- .execute()
|
|
|
- .body();
|
|
|
- JSONObject jsonResponse = new JSONObject(body);
|
|
|
- if (jsonResponse.getInt("errCode") == 0) {
|
|
|
- JSONObject data = jsonResponse.getJSONObject("data");
|
|
|
- int total = data.getInt("total");
|
|
|
- if (total > 0) {
|
|
|
- JSONArray conversations = data.getJSONArray("conversations");
|
|
|
- // 遍历当前页的所有会话
|
|
|
- for (int i = 0; i < conversations.length(); i++) {
|
|
|
- JSONObject conversation = conversations.getJSONObject(i);
|
|
|
- String convId = conversation.getString("conversationID");
|
|
|
- // 如果找到目标会话,返回其ex字段
|
|
|
- if (conversationId.equals(convId)) {
|
|
|
- return conversation.getString("ex");
|
|
|
- }
|
|
|
- }
|
|
|
- // 如果当前页没有找到且已经是最后一页,则退出循环
|
|
|
- if (conversations.length() < pageSize) {
|
|
|
- break;
|
|
|
+ // 先尝试通过 get_conversations 接口直接获取指定会话
|
|
|
+ JSONObject requestBody = new JSONObject();
|
|
|
+ requestBody.put("userID", recvID);
|
|
|
+ requestBody.put("conversationIDs", Collections.singletonList(conversationId));
|
|
|
+ String body = HttpRequest.post(IMConfig.URL + "/conversation/get_conversations")
|
|
|
+ .header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
+ .header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
+ .body(requestBody.toString())
|
|
|
+ .execute()
|
|
|
+ .body();
|
|
|
+ JSONObject jsonResponse = new JSONObject(body);
|
|
|
+ if (jsonResponse.getInt("errCode") == 0) {
|
|
|
+ JSONObject data = jsonResponse.optJSONObject("data");
|
|
|
+ if (data != null) {
|
|
|
+ JSONArray conversations = data.optJSONArray("conversations");
|
|
|
+ if (conversations != null && conversations.length() > 0) {
|
|
|
+ return conversations.getJSONObject(0).optString("ex", null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 备用方案:如果上面的接口不可用,回退到分页查询但增大每页数量
|
|
|
+ log.warn("get_conversations 接口调用失败,回退到分页查询, recvID={}, conversationId={}", recvID, conversationId);
|
|
|
+ return getIMListFallback(recvID, conversationId);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("getIMList 异常,回退到分页查询, recvID={}, conversationId={}", recvID, conversationId, e);
|
|
|
+ try {
|
|
|
+ return getIMListFallback(recvID, conversationId);
|
|
|
+ } catch (Exception ex) {
|
|
|
+ log.error("getIMListFallback 异常", ex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * getIMList 的备用分页查询方案(仅在 get_conversations 接口不可用时使用)
|
|
|
+ */
|
|
|
+ private String getIMListFallback(String recvID, String conversationId) {
|
|
|
+ int pageNumber = 1;
|
|
|
+ int pageSize = 100; // 增大每页数量,减少请求次数
|
|
|
+ int maxPages = 5;
|
|
|
+ String adminToken = getAdminToken();
|
|
|
+ while (pageNumber <= maxPages) {
|
|
|
+ JSONObject requestBody = new JSONObject();
|
|
|
+ requestBody.put("userID", recvID);
|
|
|
+ JSONObject pagination = new JSONObject();
|
|
|
+ pagination.put("pageNumber", pageNumber);
|
|
|
+ pagination.put("showNumber", pageSize);
|
|
|
+ requestBody.put("pagination", pagination);
|
|
|
+ String body = HttpRequest.post("https://webim.zkhj6.com/api/conversation/get_owner_conversation")
|
|
|
+ .header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
+ .header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
+ .body(requestBody.toString())
|
|
|
+ .execute()
|
|
|
+ .body();
|
|
|
+ JSONObject jsonResponse = new JSONObject(body);
|
|
|
+ if (jsonResponse.getInt("errCode") == 0) {
|
|
|
+ JSONObject data = jsonResponse.getJSONObject("data");
|
|
|
+ int total = data.getInt("total");
|
|
|
+ if (total > 0) {
|
|
|
+ JSONArray conversations = data.getJSONArray("conversations");
|
|
|
+ for (int i = 0; i < conversations.length(); i++) {
|
|
|
+ JSONObject conversation = conversations.getJSONObject(i);
|
|
|
+ String convId = conversation.getString("conversationID");
|
|
|
+ if (conversationId.equals(convId)) {
|
|
|
+ return conversation.getString("ex");
|
|
|
}
|
|
|
- } else {
|
|
|
- // 如果没有数据,直接退出循环
|
|
|
+ }
|
|
|
+ if (conversations.length() < pageSize) {
|
|
|
break;
|
|
|
}
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
}
|
|
|
- // 移动到下一页
|
|
|
- pageNumber++;
|
|
|
}
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
+ pageNumber++;
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
@@ -446,6 +506,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
String result1 = HttpRequest.post(IMConfig.URL+"/user/get_users_info")
|
|
|
.header("operationID", String.valueOf(time))
|
|
|
.header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
.body(jsonBody)
|
|
|
.execute()
|
|
|
.body();
|
|
|
@@ -468,6 +529,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
String result2 = HttpRequest.post(IMConfig.URL+"/user/update_user_info_ex")
|
|
|
.header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
.header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
.body(jsonBody1)
|
|
|
.execute()
|
|
|
.body();
|
|
|
@@ -490,6 +552,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
String result1 = HttpRequest.post(IMConfig.URL+"/friend/delete_friend")
|
|
|
.header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
.header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
.body(jsonBody1)
|
|
|
.execute()
|
|
|
.body();
|
|
|
@@ -502,6 +565,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
String result2 = HttpRequest.post(IMConfig.URL+"/friend/delete_friend")
|
|
|
.header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
.header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
.body(jsonBody2)
|
|
|
.execute()
|
|
|
.body();
|
|
|
@@ -514,6 +578,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
String result2 = HttpRequest.post(IMConfig.URL+"/friend/add_black")
|
|
|
.header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
.header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
.body(jsonBody2)
|
|
|
.execute()
|
|
|
.body();*/
|
|
|
@@ -572,24 +637,25 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
|
|
|
@Override
|
|
|
public OpenImResponseDTO openIMSendMsg(OpenImMsgDTO openImMsgDTO) {
|
|
|
- log.info("进入发消息的方法");
|
|
|
+ log.debug("进入发消息的方法");
|
|
|
String adminToken = getAdminToken();
|
|
|
JSONObject jsonObject = new JSONObject(openImMsgDTO);
|
|
|
String url = IMConfig.URL+"/msg/send_msg";
|
|
|
log.info("请求url: {}",url);
|
|
|
- log.info("发送消息的请求体:\n{}", jsonObject.toString());
|
|
|
+ log.debug("发送消息的请求体:\n{}", jsonObject.toString());
|
|
|
long time = new Date().getTime();
|
|
|
|
|
|
- log.info("请求header: token={},operationID={}",adminToken,time);
|
|
|
+ log.debug("请求header: token={},operationID={}",adminToken,time);
|
|
|
String result = HttpRequest.post(url)
|
|
|
.header("operationID", time + "")
|
|
|
.header("token",adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
.body(jsonObject.toString())
|
|
|
.execute()
|
|
|
.body();
|
|
|
|
|
|
OpenImResponseDTO responseDTO= JSONUtil.toBean(result,OpenImResponseDTO.class);
|
|
|
- log.info("发送消息返回内容:\n{}", result);
|
|
|
+ log.debug("发送消息返回内容:\n{}", result);
|
|
|
return responseDTO;
|
|
|
}
|
|
|
@Override
|
|
|
@@ -628,7 +694,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
openImMsgDTO.setContentType(110);
|
|
|
openImMsgDTO.setSessionType(1);
|
|
|
// 输出格式化JSON日志
|
|
|
- log.info("课程消息: {}", JSON.toJSONString(openImMsgDTO));
|
|
|
+ log.info("课程消息发送, sendID={}, recvID={}", openImMsgDTO.getSendID(), openImMsgDTO.getRecvID());
|
|
|
OpenImResponseDTO openImResponseDTO = openIMSendMsg(openImMsgDTO);
|
|
|
openImMsgDTO = null;
|
|
|
content = null;
|
|
|
@@ -782,7 +848,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
openImEditConversationDTO.setConversation(openImConversationDTO);
|
|
|
|
|
|
OpenImResponseDTO openImResponseDTO1 = editConversation(openImEditConversationDTO);
|
|
|
- log.info("修改回话返回参数:{}",openImResponseDTO1);
|
|
|
+ log.debug("修改回话返回参数:{}",openImResponseDTO1);
|
|
|
|
|
|
}
|
|
|
return openImResponseDTO;
|
|
|
@@ -870,7 +936,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
openImEditConversationDTO.setConversation(openImConversationDTO);
|
|
|
|
|
|
OpenImResponseDTO openImResponseDTO1 = editConversation(openImEditConversationDTO);
|
|
|
- log.info("修改回话返回参数:{}",openImResponseDTO1);
|
|
|
+ log.debug("修改回话返回参数:{}",openImResponseDTO1);
|
|
|
|
|
|
}
|
|
|
return openImResponseDTO;
|
|
|
@@ -898,6 +964,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
String body = HttpRequest.post(IMConfig.URL+"/conversation/set_conversations")
|
|
|
.header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
.header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
.body(jsonObject.toString())
|
|
|
.execute()
|
|
|
.body();
|
|
|
@@ -930,6 +997,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
String body = HttpRequest.post(IMConfig.URL+"/friend/is_friend")
|
|
|
.header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
.header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
.body(jsonObject.toString())
|
|
|
.execute()
|
|
|
.body();
|
|
|
@@ -937,40 +1005,84 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
return responseDTO;
|
|
|
}
|
|
|
/**
|
|
|
- * 添加好友
|
|
|
+ * 添加好友(优化:带Redis缓存,减少isFriend请求次数)
|
|
|
*/
|
|
|
@Override
|
|
|
public OpenImResponseDTO importFriend(String ownerUserID, List<String> friendUserIDs) {
|
|
|
- //先检查用户是否存在好友关系
|
|
|
- List<String> newFriendIds = new ArrayList<>();
|
|
|
+ // 过滤掉已缓存为好友关系的用户
|
|
|
+ List<String> needCheckIds = new ArrayList<>();
|
|
|
for (String friendUserID : friendUserIDs) {
|
|
|
- OpenImResponseDTO friend = isFriend(ownerUserID,friendUserID);
|
|
|
- if (friend.getErrCode()==0){
|
|
|
- Object data = friend.getData();
|
|
|
- cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(data);
|
|
|
- Boolean inUser1Friends = (Boolean)jsonObject.get("inUser1Friends");
|
|
|
- Boolean inUser2Friends = (Boolean)jsonObject.get("inUser2Friends");
|
|
|
- //如果不存在好友关系
|
|
|
- if (!inUser1Friends&&!inUser2Friends){
|
|
|
+ String friendCacheKey = IM_FRIEND_STATUS_KEY + ownerUserID + ":" + friendUserID;
|
|
|
+ Object cached = redisCache.getCacheObject(friendCacheKey);
|
|
|
+ if (cached != null && "1".equals(cached.toString())) {
|
|
|
+ // 已是好友,跳过
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ needCheckIds.add(friendUserID);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (needCheckIds.isEmpty()) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 批量检查好友关系(每次最多50个,避免单次请求过大)
|
|
|
+ List<String> newFriendIds = new ArrayList<>();
|
|
|
+ int checkBatchSize = 50;
|
|
|
+ for (int i = 0; i < needCheckIds.size(); i += checkBatchSize) {
|
|
|
+ List<String> batch = needCheckIds.subList(i, Math.min(i + checkBatchSize, needCheckIds.size()));
|
|
|
+ for (String friendUserID : batch) {
|
|
|
+ try {
|
|
|
+ OpenImResponseDTO friend = isFriend(ownerUserID, friendUserID);
|
|
|
+ if (friend.getErrCode() == 0) {
|
|
|
+ Object data = friend.getData();
|
|
|
+ cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(data);
|
|
|
+ Boolean inUser1Friends = (Boolean) jsonObject.get("inUser1Friends");
|
|
|
+ Boolean inUser2Friends = (Boolean) jsonObject.get("inUser2Friends");
|
|
|
+ if (inUser1Friends && inUser2Friends) {
|
|
|
+ // 已是好友,缓存结果
|
|
|
+ String friendCacheKey = IM_FRIEND_STATUS_KEY + ownerUserID + ":" + friendUserID;
|
|
|
+ redisCache.setCacheObject(friendCacheKey, "1", IM_FRIEND_CACHE_SECONDS, TimeUnit.SECONDS);
|
|
|
+ } else if (!inUser1Friends && !inUser2Friends) {
|
|
|
+ // 不存在好友关系
|
|
|
+ newFriendIds.add(friendUserID);
|
|
|
+ } else {
|
|
|
+ // 单向好友,也需要添加
|
|
|
+ newFriendIds.add(friendUserID);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("检查好友关系异常 ownerUserID={}, friendUserID={}", ownerUserID, friendUserID, e);
|
|
|
+ // 异常时仍然尝试添加好友
|
|
|
newFriendIds.add(friendUserID);
|
|
|
- //friendUserIDs.remove(friendUserID);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- if (newFriendIds.size()<=0){
|
|
|
+
|
|
|
+ if (newFriendIds.isEmpty()) {
|
|
|
return null;
|
|
|
}
|
|
|
+
|
|
|
String adminToken = getAdminToken();
|
|
|
JSONObject jsonObject = new JSONObject();
|
|
|
- jsonObject.put("ownerUserID",ownerUserID);
|
|
|
- jsonObject.put("friendUserIDs",newFriendIds);
|
|
|
- String body = HttpRequest.post(IMConfig.URL+"/friend/import_friend")
|
|
|
+ jsonObject.put("ownerUserID", ownerUserID);
|
|
|
+ jsonObject.put("friendUserIDs", newFriendIds);
|
|
|
+ String body = HttpRequest.post(IMConfig.URL + "/friend/import_friend")
|
|
|
.header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
.header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
.body(jsonObject.toString())
|
|
|
.execute()
|
|
|
.body();
|
|
|
- OpenImResponseDTO responseDTO= JSONUtil.toBean(body,OpenImResponseDTO.class);
|
|
|
+ OpenImResponseDTO responseDTO = JSONUtil.toBean(body, OpenImResponseDTO.class);
|
|
|
+
|
|
|
+ // 添加好友成功后缓存好友关系
|
|
|
+ if (responseDTO.getErrCode() == 0) {
|
|
|
+ for (String friendId : newFriendIds) {
|
|
|
+ String friendCacheKey = IM_FRIEND_STATUS_KEY + ownerUserID + ":" + friendId;
|
|
|
+ redisCache.setCacheObject(friendCacheKey, "1", IM_FRIEND_CACHE_SECONDS, TimeUnit.SECONDS);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return responseDTO;
|
|
|
}
|
|
|
|
|
|
@@ -981,22 +1093,18 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
* @return
|
|
|
*/@Override
|
|
|
public R accountCheck(String userId,String type){
|
|
|
+ // 优化:先查Redis缓存,已注册的用户直接跳过HTTP检查
|
|
|
+ String cacheKey = IM_ACCOUNT_REGISTERED_KEY + userId;
|
|
|
+ Object cached = redisCache.getCacheObject(cacheKey);
|
|
|
+ if (cached != null) {
|
|
|
+ // 已注册,直接获取token
|
|
|
+ return getUserToken(userId);
|
|
|
+ }
|
|
|
+
|
|
|
String adminToken = getAdminToken();
|
|
|
JSONObject requestBody = new JSONObject();
|
|
|
// 解析响应
|
|
|
if (StringUtil.isNotEmpty(adminToken)) {
|
|
|
- //查询用户是否注册
|
|
|
- /*switch (type){
|
|
|
- case "1":
|
|
|
- userId = "U"+userId;
|
|
|
- break;
|
|
|
- case "2":
|
|
|
- userId = userId;
|
|
|
- break;
|
|
|
- case "3":
|
|
|
- userId = userId;
|
|
|
- break;
|
|
|
- }*/
|
|
|
ArrayList<String> userIds = new ArrayList<>();
|
|
|
requestBody = new JSONObject();
|
|
|
userIds.add(userId);
|
|
|
@@ -1004,6 +1112,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
String body = HttpRequest.post(IMConfig.URL+"/user/account_check")
|
|
|
.header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
.header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
.body(requestBody.toString())
|
|
|
.execute()
|
|
|
.body();
|
|
|
@@ -1022,13 +1131,11 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
s = userId.replaceFirst("^"+"C", "");
|
|
|
CompanyUser companyUser = companyUserMapper.selectCompanyUserByCompanyUserId(Long.parseLong(s));
|
|
|
if (null==companyUser){
|
|
|
-// return R.error("用户不存在");
|
|
|
log.error("异步执行IM注册/添加好友失败,失败原因:{},userId:{},type:{}", "销售用户不存在",userId, type);
|
|
|
throw new ServiceException("用户不存在");
|
|
|
}
|
|
|
Company company = companyMapper.selectCompanyById(companyUser.getCompanyId());
|
|
|
map.put("userID",userId);
|
|
|
- //map.put("nickname",companyUser.getImNickName());
|
|
|
map.put("nickname",companyUser.getNickName());
|
|
|
map.put("faceURL",companyUser.getAvatar());
|
|
|
break;
|
|
|
@@ -1036,7 +1143,6 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
s = userId.replaceFirst("^"+"U", "");
|
|
|
FsUser fsUser = fsUserMapper.selectFsUserByUserId(Long.parseLong(s));
|
|
|
if (null==fsUser){
|
|
|
-// return R.error("用户不存在");
|
|
|
log.error("异步执行IM注册/添加好友失败,失败原因:{},userId:{},type:{}", "user用户不存在", userId, type);
|
|
|
throw new ServiceException("用户不存在");
|
|
|
}
|
|
|
@@ -1048,7 +1154,6 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
s = userId.replaceFirst("^"+"D", "");
|
|
|
FsDoctor fsDoctor = fsDoctorMapper.selectFsDoctorByDoctorId(Long.parseLong(s));
|
|
|
if (null==fsDoctor){
|
|
|
-// return R.error("用户不存在");
|
|
|
log.error("异步执行IM注册/添加好友失败,失败原因:{},userId:{},type:{}", "医生用户不存在", userId, type);
|
|
|
throw new ServiceException("用户不存在");
|
|
|
}
|
|
|
@@ -1064,39 +1169,177 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
requestBody.put("users", users);
|
|
|
HttpRequest.post(IMConfig.URL+"/user/user_register")
|
|
|
.header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
- .header("token", adminToken).body(requestBody.toString()).execute().body();
|
|
|
+ .header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
+ .body(requestBody.toString()).execute().body();
|
|
|
}
|
|
|
+ // 注册成功或已注册,写入缓存
|
|
|
+ redisCache.setCacheObject(cacheKey, "1", IM_ACCOUNT_CACHE_SECONDS, TimeUnit.SECONDS);
|
|
|
} else {
|
|
|
-// return R.error("返回结果为空");
|
|
|
log.error("异步执行IM注册/添加好友失败,失败原因:{},json结果:{}", "返回结果为空", jsonObject);
|
|
|
throw new ServiceException("返回结果为空");
|
|
|
}
|
|
|
- /* HashMap<String, String> tokenMap = new HashMap<>();
|
|
|
- tokenMap.put("platformID","1");
|
|
|
- tokenMap.put("userID",userId);*/
|
|
|
- requestBody = new JSONObject();
|
|
|
- requestBody.put("platformID",5);
|
|
|
- requestBody.put("userID",userId);
|
|
|
- String body1 = HttpRequest.post(IMConfig.URL+"/auth/get_user_token")
|
|
|
- .header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
- .header("token", adminToken)
|
|
|
- .body(requestBody.toString()).execute().body();
|
|
|
- JSONObject userJson = new JSONObject(body1);
|
|
|
- Integer errCode = (Integer)userJson.get("errCode");
|
|
|
- if (errCode==0){
|
|
|
- JSONObject userData = userJson.getJSONObject("data");
|
|
|
- String userToken = userData.getString("token");
|
|
|
- return R.ok().put("token", userToken);
|
|
|
- }
|
|
|
-// return R.error("注册失败");
|
|
|
- log.error("异步执行IM注册/添加好友失败,errCode:{}", errCode);
|
|
|
- throw new ServiceException("注册失败");
|
|
|
+ return getUserToken(userId);
|
|
|
} else {
|
|
|
-// return R.error("获取管理员token失败");
|
|
|
log.error("异步执行IM注册/添加好友失败,原因:{}, adminToken:{}", "获取管理员token失败", adminToken);
|
|
|
throw new ServiceException("获取管理员token失败");
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量账号检查与注册(优化:一次HTTP请求检查多个用户,减少请求次数)
|
|
|
+ * @param userIds 用户ID列表
|
|
|
+ * @param type 1用户,2销售,3医生
|
|
|
+ */
|
|
|
+ private void batchAccountCheck(List<String> userIds, String type) {
|
|
|
+ if (CollectionUtil.isEmpty(userIds)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 过滤掉已缓存的已注册用户
|
|
|
+ List<String> needCheckIds = userIds.stream()
|
|
|
+ .filter(id -> redisCache.getCacheObject(IM_ACCOUNT_REGISTERED_KEY + id) == null)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ if (needCheckIds.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ String adminToken = getAdminToken();
|
|
|
+ // 批量检查账号状态,每次最多100个
|
|
|
+ int batchSize = 100;
|
|
|
+ for (int i = 0; i < needCheckIds.size(); i += batchSize) {
|
|
|
+ List<String> batch = needCheckIds.subList(i, Math.min(i + batchSize, needCheckIds.size()));
|
|
|
+ JSONObject requestBody = new JSONObject();
|
|
|
+ requestBody.put("checkUserIDs", batch);
|
|
|
+ try {
|
|
|
+ String body = HttpRequest.post(IMConfig.URL + "/user/account_check")
|
|
|
+ .header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
+ .header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
+ .body(requestBody.toString())
|
|
|
+ .execute()
|
|
|
+ .body();
|
|
|
+ JSONObject jsonObject = new JSONObject(body);
|
|
|
+ JSONArray results = jsonObject.getJSONObject("data").getJSONArray("results");
|
|
|
+ List<HashMap<String, String>> toRegister = new ArrayList<>();
|
|
|
+ Set<String> registeredIds = new HashSet<>();
|
|
|
+
|
|
|
+ for (int j = 0; j < results.length(); j++) {
|
|
|
+ JSONObject resultObj = results.getJSONObject(j);
|
|
|
+ String uid = resultObj.getString("userID");
|
|
|
+ int accountStatus = resultObj.getInt("accountStatus");
|
|
|
+ if (accountStatus == 0) {
|
|
|
+ // 未注册,需要注册
|
|
|
+ HashMap<String, String> map = buildUserRegisterInfo(uid, type);
|
|
|
+ if (map != null) {
|
|
|
+ toRegister.add(map);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ registeredIds.add(uid);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 缓存已注册的用户
|
|
|
+ for (String uid : registeredIds) {
|
|
|
+ redisCache.setCacheObject(IM_ACCOUNT_REGISTERED_KEY + uid, "1", IM_ACCOUNT_CACHE_SECONDS, TimeUnit.SECONDS);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 批量注册未注册的用户
|
|
|
+ if (!toRegister.isEmpty()) {
|
|
|
+ JSONObject regBody = new JSONObject();
|
|
|
+ regBody.put("users", toRegister);
|
|
|
+ String regResult = HttpRequest.post(IMConfig.URL + "/user/user_register")
|
|
|
+ .header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
+ .header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
+ .body(regBody.toString())
|
|
|
+ .execute()
|
|
|
+ .body();
|
|
|
+ JSONObject regJson = new JSONObject(regResult);
|
|
|
+ if (regJson.getInt("errCode") == 0) {
|
|
|
+ // 注册成功,写入缓存
|
|
|
+ for (HashMap<String, String> user : toRegister) {
|
|
|
+ redisCache.setCacheObject(IM_ACCOUNT_REGISTERED_KEY + user.get("userID"), "1", IM_ACCOUNT_CACHE_SECONDS, TimeUnit.SECONDS);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.error("批量注册IM账号失败: {}", regResult);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("批量检查IM账号异常", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建用户注册信息
|
|
|
+ */
|
|
|
+ private HashMap<String, String> buildUserRegisterInfo(String userId, String type) {
|
|
|
+ HashMap<String, String> map = new HashMap<>();
|
|
|
+ String s;
|
|
|
+ switch (type) {
|
|
|
+ case "2":
|
|
|
+ s = userId.replaceFirst("^C", "");
|
|
|
+ CompanyUser companyUser = companyUserMapper.selectCompanyUserByCompanyUserId(Long.parseLong(s));
|
|
|
+ if (null == companyUser) {
|
|
|
+ log.error("构建IM注册信息失败,销售用户不存在,userId:{},type:{}", userId, type);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ map.put("userID", userId);
|
|
|
+ map.put("nickname", companyUser.getNickName());
|
|
|
+ map.put("faceURL", companyUser.getAvatar());
|
|
|
+ break;
|
|
|
+ case "1":
|
|
|
+ s = userId.replaceFirst("^U", "");
|
|
|
+ FsUser fsUser = fsUserMapper.selectFsUserByUserId(Long.parseLong(s));
|
|
|
+ if (null == fsUser) {
|
|
|
+ log.error("构建IM注册信息失败,user用户不存在,userId:{},type:{}", userId, type);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ map.put("userID", userId);
|
|
|
+ map.put("nickname", StringUtils.isEmpty(fsUser.getNickName()) ? "微信用户" : fsUser.getNickName());
|
|
|
+ map.put("faceURL", fsUser.getAvatar());
|
|
|
+ break;
|
|
|
+ case "3":
|
|
|
+ s = userId.replaceFirst("^D", "");
|
|
|
+ FsDoctor fsDoctor = fsDoctorMapper.selectFsDoctorByDoctorId(Long.parseLong(s));
|
|
|
+ if (null == fsDoctor) {
|
|
|
+ log.error("构建IM注册信息失败,医生用户不存在,userId:{},type:{}", userId, type);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ map.put("userID", userId);
|
|
|
+ map.put("nickname", fsDoctor.getDoctorName());
|
|
|
+ map.put("faceURL", fsDoctor.getAvatar());
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取用户Token(从accountCheck中抽取)
|
|
|
+ */
|
|
|
+ private R getUserToken(String userId) {
|
|
|
+ String adminToken = getAdminToken();
|
|
|
+ JSONObject requestBody = new JSONObject();
|
|
|
+ requestBody.put("platformID", 5);
|
|
|
+ requestBody.put("userID", userId);
|
|
|
+ String body1 = HttpRequest.post(IMConfig.URL + "/auth/get_user_token")
|
|
|
+ .header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
+ .header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
+ .body(requestBody.toString()).execute().body();
|
|
|
+ JSONObject userJson = new JSONObject(body1);
|
|
|
+ Integer errCode = (Integer) userJson.get("errCode");
|
|
|
+ if (errCode == 0) {
|
|
|
+ JSONObject userData = userJson.getJSONObject("data");
|
|
|
+ String userToken = userData.getString("token");
|
|
|
+ return R.ok().put("token", userToken);
|
|
|
+ }
|
|
|
+ log.error("获取IM用户token失败,errCode:{}", errCode);
|
|
|
+ throw new ServiceException("注册失败");
|
|
|
+ }
|
|
|
// @Async
|
|
|
@Override
|
|
|
public void checkAndImportFriend(Long companyUserId,String fsUserId) {
|
|
|
@@ -1134,6 +1377,40 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 批量注册并添加好友(优化:批量accountCheck + 批量importFriend,大幅减少HTTP请求次数)
|
|
|
+ * @param companyUserId 销售用户ID
|
|
|
+ * @param fsUserIds 用户ID列表(不带U前缀)
|
|
|
+ * @param cropId 企业ID
|
|
|
+ * @param isUpdate 是否更新好友信息
|
|
|
+ */
|
|
|
+ public void batchCheckAndImportFriend(Long companyUserId, List<String> fsUserIds, String cropId, boolean isUpdate) {
|
|
|
+ if (CollectionUtil.isEmpty(fsUserIds)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ // 1. 先注册销售账号
|
|
|
+ accountCheck("C" + companyUserId, "2");
|
|
|
+
|
|
|
+ // 2. 批量注册用户账号
|
|
|
+ List<String> userIMIds = fsUserIds.stream().map(id -> "U" + id).collect(Collectors.toList());
|
|
|
+ batchAccountCheck(userIMIds, "1");
|
|
|
+
|
|
|
+ // 3. 批量导入好友关系
|
|
|
+ importFriend("C" + companyUserId, userIMIds);
|
|
|
+
|
|
|
+ // 4. 是否更新好友信息
|
|
|
+ if (isUpdate && !fsUserIds.isEmpty()) {
|
|
|
+ String firstUserId = "U" + fsUserIds.get(0);
|
|
|
+ ArrayList<String> userIds = new ArrayList<>();
|
|
|
+ userIds.add(firstUserId);
|
|
|
+ updateFriendByDianBo("C" + companyUserId, userIds, cropId);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("批量注册/添加好友失败, companyUserId={}", companyUserId, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
@Override
|
|
|
@Transactional
|
|
|
@@ -1142,17 +1419,18 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
String adminToken = getAdminToken();
|
|
|
JSONObject jsonObject = new JSONObject(openImBatchMsgDTO);
|
|
|
String url = IMConfig.URL+"/msg/batch_send_msg";
|
|
|
- log.info("请求url: {},\n请求参数:{}", url, jsonObject);
|
|
|
+ log.info("请求url: {},接收人数:{}", url, openImBatchMsgDTO.getRecvIDs() != null ? openImBatchMsgDTO.getRecvIDs().size() : 0);
|
|
|
long timestamp = System.currentTimeMillis();
|
|
|
- log.info("请求header,operationID:{},token:{}", timestamp, adminToken);
|
|
|
+ log.debug("请求header,operationID:{},token:{}", timestamp, adminToken);
|
|
|
|
|
|
String result = HttpRequest.post(url)
|
|
|
.header("operationID", timestamp + "")
|
|
|
.header("token",adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
.body(jsonObject.toString())
|
|
|
.execute()
|
|
|
.body();
|
|
|
- log.info("批量发送消息返回内容:\n{}", result);
|
|
|
+ log.debug("批量发送消息返回内容:\n{}", result);
|
|
|
OpenImResponseDTO responseDTO=new OpenImResponseDTO();
|
|
|
if (result != null && result.startsWith("<html")) {
|
|
|
log.error("网关超时返回HTML报文: {}", result);
|
|
|
@@ -1173,11 +1451,9 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
//获取需要发送的人
|
|
|
List<String> userIds = this.getRecvIds(batchSendCourseDTO);
|
|
|
|
|
|
- //注册和添加好友
|
|
|
- for (String userId : userIds) {
|
|
|
- String uId = userId.substring(1);
|
|
|
- checkAndImportFriendByDianBo(batchSendCourseDTO.getCompanyUserId(), uId,null,false);
|
|
|
- }
|
|
|
+ //优化:批量注册和添加好友(替代逐个循环调用checkAndImportFriendByDianBo)
|
|
|
+ List<String> fsUserIds = userIds.stream().map(id -> id.substring(1)).collect(Collectors.toList());
|
|
|
+ batchCheckAndImportFriend(batchSendCourseDTO.getCompanyUserId(), fsUserIds, null, false);
|
|
|
|
|
|
//组装发课消息数据
|
|
|
FsUserCourse fsUserCourse = fsUserCourseMapper.selectFsUserCourseByCourseId(batchSendCourseDTO.getCourseId());
|
|
|
@@ -1258,11 +1534,9 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
//获取需要发送的人
|
|
|
List<String> userIds = this.getRecvIds(batchSendCourseDTO);
|
|
|
|
|
|
- //注册和添加好友
|
|
|
- for (String userId : userIds) {
|
|
|
- String uId = userId.substring(1);
|
|
|
- checkAndImportFriendByDianBo(batchSendCourseDTO.getCompanyUserId(), uId,null,false);
|
|
|
- }
|
|
|
+ //优化:批量注册和添加好友(替代逐个循环调用checkAndImportFriendByDianBo)
|
|
|
+ List<String> fsUserIds = userIds.stream().map(id -> id.substring(1)).collect(Collectors.toList());
|
|
|
+ batchCheckAndImportFriend(batchSendCourseDTO.getCompanyUserId(), fsUserIds, null, false);
|
|
|
|
|
|
//组装发课消息数据
|
|
|
FsUserCourse fsUserCourse = fsUserCourseMapper.selectFsUserCourseByCourseId(batchSendCourseDTO.getCourseId());
|
|
|
@@ -1462,7 +1736,8 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
@Override
|
|
|
@Transactional
|
|
|
public OpenImResponseDTO batchSendCourseTask(BatchSendCourseDTO batchSendCourseDTO, OpenImBatchMsgDTO openImBatchMsgDTO, Long project, List<FsImMsgSendDetail> imMsgSendDetailList) {
|
|
|
- log.info("批量发送课程消息: \n{}", JSON.toJSONString(openImBatchMsgDTO));
|
|
|
+ log.info("批量发送课程消息, 接收人数={}", openImBatchMsgDTO.getRecvIDs() != null ? openImBatchMsgDTO.getRecvIDs().size() : 0);
|
|
|
+ log.debug("批量发送课程消息详情: \n{}", JSON.toJSONString(openImBatchMsgDTO));
|
|
|
OpenImResponseDTO openImResponseDTO = openIMBatchSendMsg(openImBatchMsgDTO);
|
|
|
// openImBatchMsgDTO = null;
|
|
|
// content = null;
|
|
|
@@ -1485,7 +1760,8 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
@Override
|
|
|
@Transactional
|
|
|
public OpenImResponseDTO batchUrgeCourseTask(OpenImBatchMsgDTO openImBatchMsgDTO, List<FsImMsgSendDetail> imMsgSendDetailList) {
|
|
|
- log.info("批量催课消息: \n{}", JSON.toJSONString(openImBatchMsgDTO));
|
|
|
+ log.info("批量催课消息, 接收人数={}", openImBatchMsgDTO.getRecvIDs() != null ? openImBatchMsgDTO.getRecvIDs().size() : 0);
|
|
|
+ log.debug("批量催课消息详情: \n{}", JSON.toJSONString(openImBatchMsgDTO));
|
|
|
OpenImResponseDTO openImResponseDTO = openIMBatchSendMsg(openImBatchMsgDTO);
|
|
|
|
|
|
// 修改发送记录
|
|
|
@@ -1527,7 +1803,8 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
batchSendCourseDTO.setUrl(url);
|
|
|
batchSendCourseDTO.setId(fsImMsgSendLog.getPeriodDaysId());
|
|
|
OpenImBatchMsgDTO openImBatchMsgDTO = makeOpenImBatchMsgDTO(batchSendCourseDTO, courseUrl, objectMapper, userIds, System.currentTimeMillis(), "发课");
|
|
|
- log.info("一键催课-发课-批量发送课程消息: \n{}", JSON.toJSONString(openImBatchMsgDTO));
|
|
|
+ log.info("一键催课-发课, 接收人数={}", openImBatchMsgDTO.getRecvIDs() != null ? openImBatchMsgDTO.getRecvIDs().size() : 0);
|
|
|
+ log.debug("一键催课-发课详情: \n{}", JSON.toJSONString(openImBatchMsgDTO));
|
|
|
this.openIMBatchSendMsg(openImBatchMsgDTO);
|
|
|
// List<FsImMsgSendDetail> imMsgSendDetailList = createImMsgSendLog("发课",batchSendCourseDTO, System.currentTimeMillis(), 2, userIds, sendUnionId);
|
|
|
}
|
|
|
@@ -1541,7 +1818,8 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
batchSendCourseDTO.setIsUrgeCourse(true);
|
|
|
batchSendCourseDTO.setSendType(2);
|
|
|
OpenImBatchMsgDTO openImBatchMsgDTO = makeOpenImBatchMsgDTO(batchSendCourseDTO, courseUrl, objectMapper, userIds, System.currentTimeMillis(), "催课");
|
|
|
- log.info("一键催课-催课-批量催课消息: \n{}", JSON.toJSONString(openImBatchMsgDTO));
|
|
|
+ log.info("一键催课-催课, 接收人数={}", openImBatchMsgDTO.getRecvIDs() != null ? openImBatchMsgDTO.getRecvIDs().size() : 0);
|
|
|
+ log.debug("一键催课-催课详情: \n{}", JSON.toJSONString(openImBatchMsgDTO));
|
|
|
openImResponseDTO = this.openIMBatchSendMsg(openImBatchMsgDTO);
|
|
|
|
|
|
List<FsImMsgSendDetail> imMsgSendDetailList = createImMsgSendLog("催课", batchSendCourseDTO, System.currentTimeMillis(), 2, userIds, fsImMsgSendLog.getSendUnionId());
|
|
|
@@ -1657,13 +1935,18 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
|
|
|
private void updateImMsgSendLog(OpenImBatchMsgDTO openImBatchMsgDTO, List<FsImMsgSendDetail> imMsgSendDetailList, OpenImResponseDTO openImResponseDTO, String logType) {
|
|
|
List<FsImMsgSendDetail> updateList = new ArrayList<>();
|
|
|
+ // 优化:提前序列化一次,避免在stream中重复序列化同一对象
|
|
|
+ final String batchMsgJson = JSON.toJSONString(openImBatchMsgDTO);
|
|
|
+ final String responseJson = StringUtils.substring(JSON.toJSONString(openImResponseDTO), 0, 3999);
|
|
|
+ final String errDltStr = StringUtils.substring(openImResponseDTO.getErrDlt(), 0, 1999);
|
|
|
+
|
|
|
if(openImResponseDTO.getErrCode() != 0){
|
|
|
// 所有都发送失败
|
|
|
List<FsImMsgSendDetail> allFailedList = imMsgSendDetailList.stream().map(v -> {
|
|
|
- v.setSendStatus(1).setParamJson(JSON.toJSONString(openImBatchMsgDTO))
|
|
|
+ v.setSendStatus(1).setParamJson(batchMsgJson)
|
|
|
.setStatus(1)
|
|
|
- .setResultMessage(StringUtils.substring(JSON.toJSONString(openImResponseDTO), 0, 3999))
|
|
|
- .setExceptionInfo(StringUtils.substring(openImResponseDTO.getErrDlt(), 0, 1999))
|
|
|
+ .setResultMessage(responseJson)
|
|
|
+ .setExceptionInfo(errDltStr)
|
|
|
.setUpdateTime(new Date());
|
|
|
return v;
|
|
|
}).collect(Collectors.toList());
|
|
|
@@ -1683,13 +1966,15 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
OpenImBatchResponseDataDTO openImBatchResponseDataDTO = JSON.parseObject(JSON.toJSONString(openImResponseDTO.getData()), OpenImBatchResponseDataDTO.class);
|
|
|
if(openImBatchResponseDataDTO != null && openImBatchResponseDataDTO.getFailedUserIDs() != null) {
|
|
|
//发送失败的
|
|
|
+ final String batchResponseJson = JSON.toJSONString(openImBatchResponseDataDTO);
|
|
|
+ final String exceptionInfo = JSON.toJSONString(openImResponseDTO.getErrDlt());
|
|
|
String[] failedUserIds = openImBatchResponseDataDTO.getFailedUserIDs();
|
|
|
List<String> failedUserIdList = Arrays.asList(failedUserIds);
|
|
|
List<FsImMsgSendDetail> failedList = imMsgSendDetailList.stream().filter(v -> failedUserIdList.contains("U" + v.getUserId())).map(v -> {
|
|
|
- v.setSendStatus(1).setParamJson(JSON.toJSONString(openImBatchMsgDTO))
|
|
|
+ v.setSendStatus(1).setParamJson(batchMsgJson)
|
|
|
.setStatus(1)
|
|
|
- .setResultMessage(JSON.toJSONString(openImBatchResponseDataDTO))
|
|
|
- .setExceptionInfo(JSON.toJSONString(openImResponseDTO.getErrDlt()))
|
|
|
+ .setResultMessage(batchResponseJson)
|
|
|
+ .setExceptionInfo(exceptionInfo)
|
|
|
.setUpdateTime(new Date());
|
|
|
return v;
|
|
|
}).collect(Collectors.toList());
|
|
|
@@ -1730,9 +2015,16 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
* @return
|
|
|
*/
|
|
|
public OpenImResponseDTO updateFriendByDianBo(String ownerUserID, List<String> friendUserIDs,String cropId) {
|
|
|
- //先检查用户是否存在好友关系
|
|
|
- //List<String> newFriendIds = new ArrayList<>();
|
|
|
+ // 优化:先查缓存判断好友关系,避免每次都调 isFriend HTTP 请求
|
|
|
+ boolean hasFriendRelation = false;
|
|
|
for (String friendUserID : friendUserIDs) {
|
|
|
+ String friendCacheKey = IM_FRIEND_STATUS_KEY + ownerUserID + ":" + friendUserID;
|
|
|
+ Object cached = redisCache.getCacheObject(friendCacheKey);
|
|
|
+ if (cached != null && "1".equals(cached.toString())) {
|
|
|
+ hasFriendRelation = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ // 缓存没有,调HTTP检查
|
|
|
OpenImResponseDTO friend = isFriend(ownerUserID,friendUserID);
|
|
|
if (friend.getErrCode()==0){
|
|
|
Object data = friend.getData();
|
|
|
@@ -1742,10 +2034,16 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
//如果不存在好友关系,则不执行im修改好友信息
|
|
|
if (!inUser1Friends&&!inUser2Friends){
|
|
|
return null;
|
|
|
- //friendUserIDs.remove(friendUserID);
|
|
|
+ } else {
|
|
|
+ // 存在好友关系,缓存
|
|
|
+ redisCache.setCacheObject(friendCacheKey, "1", IM_FRIEND_CACHE_SECONDS, TimeUnit.SECONDS);
|
|
|
+ hasFriendRelation = true;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ if (!hasFriendRelation) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
List<String> remark = qwExternalContactMapper.selectRemarkByCompanyUserAndFsUser(friendUserIDs.get(0).replaceFirst("^scrmU", ""), ownerUserID.replaceFirst("^scrmC", ""),cropId);
|
|
|
if (CollectionUtils.isEmpty(remark)||remark.size()<=0){
|
|
|
return null;
|
|
|
@@ -1758,6 +2056,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
String body = HttpRequest.post(IMConfig.URL+"/friend/update_friends")
|
|
|
.header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
.header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
.body(jsonObject.toString())
|
|
|
.execute()
|
|
|
.body();
|
|
|
@@ -1893,6 +2192,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
String body = HttpRequest.post(IMConfig.URL+"/friend/get_friend_list")
|
|
|
.header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
.header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
.body(jsonObject.toString())
|
|
|
.execute()
|
|
|
.body();
|
|
|
@@ -1902,6 +2202,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
String body = HttpRequest.post(IMConfig.URL+"/friend/get_self_friend_apply_list")
|
|
|
.header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
.header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
.body(jsonObject.toString())
|
|
|
.execute()
|
|
|
.body();
|
|
|
@@ -1911,6 +2212,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
String body = HttpRequest.post(IMConfig.URL+"/friend/get_friend_apply_list")
|
|
|
.header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
.header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
.body(jsonObject.toString())
|
|
|
.execute()
|
|
|
.body();
|
|
|
@@ -1972,6 +2274,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
String body = HttpRequest.post(IMConfig.URL+"/user/get_users_info")
|
|
|
.header("operationID", String.valueOf(System.currentTimeMillis()))
|
|
|
.header("token", adminToken)
|
|
|
+ .timeout(HTTP_TIMEOUT_MS)
|
|
|
.body(jsonObject.toString())
|
|
|
.execute()
|
|
|
.body();
|
|
|
@@ -1994,7 +2297,8 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
public OpenImResponseDTO batchSendTextMessage(String senderId, List<String> receiverIds, String textContent,
|
|
|
String pushTitle, String pushDesc, String ex) {
|
|
|
try {
|
|
|
- log.info("批量发送文本消息 - 发送人: {}, 接收人数: {}, 内容: {}", senderId, receiverIds.size(), textContent);
|
|
|
+ log.info("批量发送文本消息 - 发送人: {}, 接收人数: {}", senderId, receiverIds.size());
|
|
|
+ log.debug("批量发送文本消息内容: {}", textContent);
|
|
|
|
|
|
// 构建批量发送消息DTO
|
|
|
OpenImBatchMsgDTO batchMsgDTO = new OpenImBatchMsgDTO();
|
|
|
@@ -2029,7 +2333,7 @@ public class OpenIMServiceImpl implements OpenIMService {
|
|
|
batchMsgDTO.setNotOfflinePush(false); // 允许离线推送
|
|
|
batchMsgDTO.setSendTime(System.currentTimeMillis()); // 当前时间
|
|
|
|
|
|
- log.info("批量发送文本消息请求: {}", JSON.toJSONString(batchMsgDTO));
|
|
|
+ log.debug("批量发送文本消息请求详情: {}", JSON.toJSONString(batchMsgDTO));
|
|
|
|
|
|
// 调用批量发送接口
|
|
|
OpenImResponseDTO response = this.openIMBatchSendMsg(batchMsgDTO);
|