Commit 3596e8a9 by 陈前凌

Merge remote-tracking branch 'origin/xiaohudou_20220427' into xiaohudou_20220427

parents 539e0d75 3ed2e464
...@@ -42,7 +42,7 @@ public class InboxAction { ...@@ -42,7 +42,7 @@ public class InboxAction {
@ApiOperation(value = "消息修改为已接收状态") @ApiOperation(value = "消息修改为已接收状态")
public WsResponse<Map<String, Boolean>> updateImMsgReceived(@Validated ImMsgReceivedStatusUpdate data) throws Exception { public WsResponse<Map<String, Boolean>> updateImMsgReceived(@Validated ImMsgReceivedStatusUpdate data) throws Exception {
log.info("消息修改为已接收状态入参 {}", JSON.toJSONString(data)); log.info("消息修改为已接收状态入参 {}", JSON.toJSONString(data));
imInboxService.updateImMsgReceived(data); // imInboxService.updateImMsgReceived(data);
return WsResponse.ok(); return WsResponse.ok();
} }
...@@ -54,7 +54,7 @@ public class InboxAction { ...@@ -54,7 +54,7 @@ public class InboxAction {
public WsResponse<Map<String, Boolean>> updateInMsgReadUpdate(MsgReadStatusUpdateParam data) throws Exception { public WsResponse<Map<String, Boolean>> updateInMsgReadUpdate(MsgReadStatusUpdateParam data) throws Exception {
log.info("消息修改为已读状态入参 {}", JSON.toJSONString(data)); log.info("消息修改为已读状态入参 {}", JSON.toJSONString(data));
if (CollectionUtils.isEmpty(data.getMsgIds())) { if (CollectionUtils.isEmpty(data.getMsgIds())) {
return WsResponse.fail(ApiCode.PARAMETER_EXCEPTION); return WsResponse.ok();
} }
imInboxService.updateImMsgRead(data); imInboxService.updateImMsgRead(data);
return WsResponse.ok(); return WsResponse.ok();
......
package com.wecloud.im.action; package com.wecloud.im.action;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
...@@ -33,6 +32,7 @@ import com.wecloud.im.service.ImInboxService; ...@@ -33,6 +32,7 @@ import com.wecloud.im.service.ImInboxService;
import com.wecloud.im.service.ImMessageService; import com.wecloud.im.service.ImMessageService;
import com.wecloud.im.ws.enums.MsgTypeEnum; import com.wecloud.im.ws.enums.MsgTypeEnum;
import com.wecloud.im.ws.enums.WsResponseCmdEnum; import com.wecloud.im.ws.enums.WsResponseCmdEnum;
import com.wecloud.im.ws.manager.ChannelManager;
import com.wecloud.im.ws.model.WsResponse; import com.wecloud.im.ws.model.WsResponse;
import com.wecloud.im.ws.model.request.PushVO; import com.wecloud.im.ws.model.request.PushVO;
import com.wecloud.im.ws.sender.ChannelSender; import com.wecloud.im.ws.sender.ChannelSender;
...@@ -113,14 +113,15 @@ public class NormalChatAction { ...@@ -113,14 +113,15 @@ public class NormalChatAction {
// 给所有人(在线+离线)遍历发送 // 给所有人(在线+离线)遍历发送
// 先查询该会话所有成员 // 先查询该会话所有成员
long time1 = System.currentTimeMillis();
List<ImConversationMembers> membersList = ehcacheService.getEhCacheMember("member"+conversation.getId(), conversation.getId()); List<ImConversationMembers> membersList = ehcacheService.getEhCacheMember("member"+conversation.getId(), conversation.getId());
log.info("会话id{} 获取群成员列表耗时 {}", conversation.getId(), System.currentTimeMillis()-time1);
if (membersList.isEmpty()) { if (membersList.isEmpty()) {
log.info("查询会话所有成员返回空,会话ID: {}", data.getToConversation()); log.info("查询会话所有成员返回空,会话ID: {}", data.getToConversation());
WsResponse<HashMap<String, Long>> responseModel = new WsResponse<>(); WsResponse<HashMap<String, Long>> responseModel = new WsResponse<>();
ApiResult<Boolean> result = ApiResult.result(ApiCode.IS_BE_DISBAND);
responseModel.setCmd(WsResponseCmdEnum.RES.getCmdCode()); responseModel.setCmd(WsResponseCmdEnum.RES.getCmdCode());
responseModel.setCode(result.getCode()); responseModel.setCode(ApiCode.IS_BE_DISBAND.getCode());
responseModel.setMsg(result.getMessage()); responseModel.setMsg(null);
responseModel.setReqId(reqId); responseModel.setReqId(reqId);
channelSender.sendMsgLocal((NioSocketChannel) request.getSenderChannel(), responseModel); channelSender.sendMsgLocal((NioSocketChannel) request.getSenderChannel(), responseModel);
return; return;
...@@ -153,10 +154,14 @@ public class NormalChatAction { ...@@ -153,10 +154,14 @@ public class NormalChatAction {
if (!checkMsg(imClientSender, conversation, reqId, data, request.getSenderChannel(), memberMap)) { if (!checkMsg(imClientSender, conversation, reqId, data, request.getSenderChannel(), memberMap)) {
return; return;
} }
long time3 = System.currentTimeMillis();
ImMessageOnlineSend imMessageOnlineSend = assembleImMessageOnlineSend(data, imClientSender, imApplication.getId()); ImMessageOnlineSend imMessageOnlineSend = assembleImMessageOnlineSend(data, imClientSender, imApplication.getId());
log.info("会话id{} 构造消息耗时 {}", conversation.getId(), System.currentTimeMillis()-time3);
// 入库 保存收件箱 // 入库 保存收件箱
long time4 = System.currentTimeMillis();
batchSaveInbox(imApplication, imClientSender, conversation, imMessageOnlineSend.getMsgId(), membersList); batchSaveInbox(imApplication, imClientSender, conversation, imMessageOnlineSend.getMsgId(), membersList);
log.info("会话id{} 保存inbox耗时 {}", conversation.getId(), System.currentTimeMillis()-time4);
// 入库成功后 判断是否是临时会话 如果是,双方会话display状态是否是1(显示),如果不是,需要修改为是 // 入库成功后 判断是否是临时会话 如果是,双方会话display状态是否是1(显示),如果不是,需要修改为是
if (ChatTypeEnum.TEMP.getCode().equals(conversation.getChatType())) { if (ChatTypeEnum.TEMP.getCode().equals(conversation.getChatType())) {
// 木有只有私聊一种临时会话类型 // 木有只有私聊一种临时会话类型
...@@ -171,27 +176,34 @@ public class NormalChatAction { ...@@ -171,27 +176,34 @@ public class NormalChatAction {
imConversationMembersService.updateBatchById(tempMemberToUpdate); imConversationMembersService.updateBatchById(tempMemberToUpdate);
} }
} }
// final Boolean isPush = ehcacheService.getIsPush("push" + conversation.getId()); final Boolean isPush = ehcacheService.getIsPush("push" + conversation.getId());
final Boolean isPush = Boolean.TRUE;
// 多线程处理消息下发 // 多线程处理消息下发
long time5 = System.currentTimeMillis();
// 构造发送响应
WsResponse<ImMessageOnlineSend> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.ONLINE_MSG.getCmdCode());
responseModel.setCode(200);
responseModel.setMsg(null);
responseModel.setData(imMessageOnlineSend);
responseModel.setReqId(null);
for (ImConversationMembers member : membersList) { for (ImConversationMembers member : membersList) {
if (member.getFkClientId().equals(imClientSender.getId())) { if (member.getFkClientId().equals(imClientSender.getId())) {
// 不给自己发 // 不给自己发
continue; continue;
} }
SendMsgThreadPool.SEND_MSG_THREAD_POOL_EXECUTOR.execute(() -> { SendMsgThreadPool.SEND_MSG_THREAD_POOL_EXECUTOR.execute(() -> {
this.sendMsgToMember(imApplication, member, imMessageOnlineSend, data.getPush(), isPush); this.sendMsgToMember(imApplication, member, responseModel, data.getPush(), isPush);
}); });
} }
log.info("会话id{} 是否推送 {} 多线程发消息耗时 {}", conversation.getId(), isPush, System.currentTimeMillis()-time5);
// 响应发送方消息id等信息 // 响应发送方消息id等信息
response(reqId, imMessageOnlineSend, request.getSenderChannel()); response(reqId, imMessageOnlineSend, request.getSenderChannel());
} }
private void sendMsgToMember(ImApplication imApplication, ImConversationMembers member, ImMessageOnlineSend imMessageOnlineSend, PushVO push, Boolean isPush) { private void sendMsgToMember(ImApplication imApplication, ImConversationMembers member, WsResponse<ImMessageOnlineSend> responseModel, PushVO push, Boolean isPush) {
// 在线用户直接发消息 // 在线用户直接发消息
sendMsgForOnline(member.getFkClientId(), responseModel);
Boolean sendSuccess = sendMsgForOnline(member.getFkClientId(), imMessageOnlineSend);
if (isPush && !member.getDoNotDisturb()) { if (isPush && !member.getDoNotDisturb()) {
try { try {
// 异步推送系统通知消息 5分钟内推一次消息 // 异步推送系统通知消息 5分钟内推一次消息
...@@ -209,17 +221,9 @@ public class NormalChatAction { ...@@ -209,17 +221,9 @@ public class NormalChatAction {
* 发送消息给在线客户 * 发送消息给在线客户
* *
* @param receiverClientId * @param receiverClientId
* @param imMessageOnlineSend * @param responseModel
*/ */
private Boolean sendMsgForOnline(Long receiverClientId, ImMessageOnlineSend imMessageOnlineSend) { private Boolean sendMsgForOnline(Long receiverClientId, WsResponse<ImMessageOnlineSend> responseModel) {
// 封装要推给接收方的消息
WsResponse<ImMessageOnlineSend> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.ONLINE_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(imMessageOnlineSend);
responseModel.setReqId(null);
return channelSender.sendMsg(responseModel, receiverClientId); return channelSender.sendMsg(responseModel, receiverClientId);
} }
...@@ -265,10 +269,9 @@ public class NormalChatAction { ...@@ -265,10 +269,9 @@ public class NormalChatAction {
*/ */
private void response(String reqId, ImMessageOnlineSend imMessageOnlineSend, Channel channel) { private void response(String reqId, ImMessageOnlineSend imMessageOnlineSend, Channel channel) {
WsResponse<MsgVo> responseModel = new WsResponse<>(); WsResponse<MsgVo> responseModel = new WsResponse<>();
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCmd(WsResponseCmdEnum.RES.getCmdCode()); responseModel.setCmd(WsResponseCmdEnum.RES.getCmdCode());
responseModel.setCode(result.getCode()); responseModel.setCode(200);
responseModel.setMsg(result.getMessage()); responseModel.setMsg(null);
responseModel.setData(new MsgVo(imMessageOnlineSend.getMsgId(), imMessageOnlineSend.getPreMessageId(), imMessageOnlineSend.getCreateTime())); responseModel.setData(new MsgVo(imMessageOnlineSend.getMsgId(), imMessageOnlineSend.getPreMessageId(), imMessageOnlineSend.getCreateTime()));
responseModel.setReqId(reqId); responseModel.setReqId(reqId);
// 响应发送方 // 响应发送方
...@@ -286,23 +289,34 @@ public class NormalChatAction { ...@@ -286,23 +289,34 @@ public class NormalChatAction {
private void batchSaveInbox(ImApplication imApplication, ImClient clientSender, ImConversationQueryVo conversation, long messageId, private void batchSaveInbox(ImApplication imApplication, ImClient clientSender, ImConversationQueryVo conversation, long messageId,
List<ImConversationMembers> membersList) { List<ImConversationMembers> membersList) {
List<ImInbox> inboxes = Lists.newArrayList(); List<ImInbox> inboxes = Lists.newArrayList();
for (ImConversationMembers member : membersList) { try {
if (clientSender.getClientId().equals(member.getClientId())) { for (ImConversationMembers member : membersList) {
continue; if (clientSender.getClientId().equals(member.getClientId())) {
continue;
}
if (conversation.getMemberCount() > 100) {
Integer count = ChannelManager.ONLINE_USER_MAP.get(String.valueOf(member.getFkClientId()));
if (count == null) {
continue;
}
}
ImInbox imInbox = new ImInbox();
imInbox.setId(SnowflakeUtil.getId());
imInbox.setCreateTime(new Date());
imInbox.setFkAppid(imApplication.getId());
imInbox.setReceiver(member.getFkClientId());
imInbox.setFkMsgId(messageId);
imInbox.setReadMsgStatus(0);
imInbox.setReceiverMsgStatus(0);
imInbox.setFkConversationId(conversation.getId());
inboxes.add(imInbox);
} }
ImInbox imInbox = new ImInbox(); if (CollectionUtils.isNotEmpty(inboxes)) {
imInbox.setId(SnowflakeUtil.getId()); imInboxService.saveBatch(inboxes);
imInbox.setCreateTime(new Date()); }
imInbox.setFkAppid(imApplication.getId()); } catch (Exception e) {
imInbox.setReceiver(member.getFkClientId()); log.error("批量保存未读消息异常 ", e);
imInbox.setFkMsgId(messageId);
imInbox.setReadMsgStatus(0);
imInbox.setReceiverMsgStatus(0);
imInbox.setFkConversationId(conversation.getId());
inboxes.add(imInbox);
}
if (CollectionUtils.isNotEmpty(inboxes)) {
imInboxService.saveBatch(inboxes);
} }
} }
......
//package com.wecloud.im.controller;
//
//import com.wecloud.im.entity.ImApplication;
//import com.wecloud.im.param.ImApplicationPageParam;
//import com.wecloud.im.param.ImApplicationQueryVo;
//import com.wecloud.im.param.add.ImApplicationAdd;
//import com.wecloud.im.service.ImApplicationService;
//import com.wecloud.im.ws.utils.RSAGenerator;
//import io.geekidea.springbootplus.framework.common.api.ApiResult;
//import io.geekidea.springbootplus.framework.common.controller.BaseController;
//import io.geekidea.springbootplus.framework.core.pagination.Paging;
//import io.geekidea.springbootplus.framework.core.validator.groups.Add;
//import io.geekidea.springbootplus.framework.core.validator.groups.Update;
//import io.geekidea.springbootplus.framework.log.annotation.OperationLog;
//import io.geekidea.springbootplus.framework.log.enums.OperationLogType;
//import io.swagger.annotations.Api;
//import io.swagger.annotations.ApiOperation;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.BeanUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.validation.annotation.Validated;
//import org.springframework.web.bind.annotation.GetMapping;
//import org.springframework.web.bind.annotation.PostMapping;
//import org.springframework.web.bind.annotation.RequestBody;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.bind.annotation.RequestParam;
//import org.springframework.web.bind.annotation.RestController;
//
///**
// * 第三方应用表 控制器
// *
// * @author wei
// * @since 2021-04-27
// */
//@Slf4j
//@RestController
//@RequestMapping("/imApplication")
//@Api(value = "第三方应用表API", tags = {"第三方应用表"})
//public class ImApplicationController extends BaseController {
//
// public static final String ADMIN_PWD = "si0132g9ad4gd6xv8x888wd6g86aga731h6pzc1pzc68b7eln96s2360j0sjkh028sj131h0gjb";
//
// @Autowired
// private ImApplicationService imApplicationService;
//
// /**
// * 添加第三方应用表
// */
// @PostMapping("/add")
// @OperationLog(name = "添加第三方应用表", type = OperationLogType.ADD)
// @ApiOperation(value = "添加第三方应用表")
// public ApiResult<Boolean> addImApplication(@Validated(Add.class) @RequestBody ImApplicationAdd imApplicationAdd) throws Exception {
//
// if (!imApplicationAdd.getAdminPwd().equals(ADMIN_PWD)) {
// return ApiResult.fail();
// }
//
// ImApplication imApplication = new ImApplication();
// BeanUtils.copyProperties(imApplicationAdd, imApplication);
//
// // 生成AppKey
// String appKey = RSAGenerator.getAppKey(); //定义变量接收
// // 生成appSecret
// String appSecret = RSAGenerator.getAppSecret(appKey);
//
// imApplication.setAppKey(appKey);
// imApplication.setAppSecret(appSecret);
//
// boolean flag = imApplicationService.saveImApplication(imApplication);
// return ApiResult.result(flag);
// }
//
// /**
// * 修改第三方应用表
// */
// @PostMapping("/update")
// @OperationLog(name = "修改第三方应用表", type = OperationLogType.UPDATE)
// @ApiOperation(value = "修改第三方应用表")
// public ApiResult<Boolean> updateImApplication(@Validated(Update.class) @RequestBody ImApplicationAdd imApplicationAdd) throws Exception {
//
// if (!imApplicationAdd.getAdminPwd().equals(ADMIN_PWD)) {
// return ApiResult.fail();
// }
//
// ImApplication imApplication = new ImApplication();
// boolean flag = imApplicationService.updateImApplication(imApplication);
// return ApiResult.result(flag);
// }
//
// /**
// * 删除第三方应用表
// */
// @PostMapping("/delete")
// @OperationLog(name = "删除第三方应用表", type = OperationLogType.DELETE)
// @ApiOperation(value = "删除第三方应用表")
// public ApiResult<Boolean> deleteImApplication(@RequestParam("id") Long id, @RequestParam("pwd") String pwd) throws Exception {
//
// if (!pwd.equals(ADMIN_PWD)) {
// return ApiResult.fail();
// }
// boolean flag = imApplicationService.deleteImApplication(id);
// return ApiResult.result(flag);
// }
//
// /**
// * 获取第三方应用表详情
// */
// @GetMapping("/info/")
// @OperationLog(name = "第三方应用表详情", type = OperationLogType.INFO)
// @ApiOperation(value = "第三方应用表详情")
// public ApiResult<ImApplicationQueryVo> getImApplication(@RequestParam("id") Long id, @RequestParam("pwd") String pwd) throws Exception {
//
// if (!pwd.equals(ADMIN_PWD)) {
// return null;
// }
//
// ImApplicationQueryVo imApplicationQueryVo = imApplicationService.getImApplicationById(id);
// return ApiResult.ok(imApplicationQueryVo);
// }
//
// /**
// * 第三方应用表分页列表
// */
// @PostMapping("/getPageList")
// @OperationLog(name = "第三方应用表分页列表", type = OperationLogType.PAGE)
// @ApiOperation(value = "第三方应用表分页列表")
// public ApiResult<Paging<ImApplicationQueryVo>> getImApplicationPageList(@Validated @RequestBody ImApplicationPageParam imApplicationPageParam) throws Exception {
//
// if (!imApplicationPageParam.getPwd().equals(ADMIN_PWD)) {
// return null;
// }
// Paging<ImApplicationQueryVo> paging = imApplicationService.getImApplicationPageList(imApplicationPageParam);
// return ApiResult.ok(paging);
// }
//
//}
//
...@@ -92,13 +92,13 @@ public class ImFriendController extends BaseController { ...@@ -92,13 +92,13 @@ public class ImFriendController extends BaseController {
List<ImFriendBaseDto> friends = imFriendService.getFriends(currentClient); List<ImFriendBaseDto> friends = imFriendService.getFriends(currentClient);
if (isVip){ if (isVip){
// 是vip // 是vip
if (friends.size()>=10){ if (friends.size()>=500){
throw new BusinessException("vip最多只能加10个好友"); throw new BusinessException("vip最多只能加500个好友");
} }
}else { }else {
// 不是vip // 不是vip
if (friends.size()>=500){ if (friends.size()>=3){
throw new BusinessException("非vip最多只能加500个好友"); throw new BusinessException("非vip最多只能加3个好友");
} }
} }
} }
...@@ -134,13 +134,13 @@ public class ImFriendController extends BaseController { ...@@ -134,13 +134,13 @@ public class ImFriendController extends BaseController {
List<ImFriendBaseDto> friends = imFriendService.getFriends(currentClient); List<ImFriendBaseDto> friends = imFriendService.getFriends(currentClient);
if (isVip){ if (isVip){
// 是vip // 是vip
if (friends.size()>=10){ if (friends.size()>=1000){
throw new BusinessException("vip最多只能加10个好友"); throw new BusinessException("vip最多只能加1000个好友");
} }
}else { }else {
// 不是vip // 不是vip
if (friends.size()>=500){ if (friends.size()>=1000){
throw new BusinessException("非vip最多只能加500个好友"); throw new BusinessException("非vip最多只能加1000个好友");
} }
} }
} }
......
...@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; ...@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wecloud.im.entity.ImClient; import com.wecloud.im.entity.ImClient;
import com.wecloud.im.entity.ImConversationMembers; import com.wecloud.im.entity.ImConversationMembers;
import com.wecloud.im.param.ImConversationQueryVo; import com.wecloud.im.param.ImConversationQueryVo;
import com.wecloud.im.ws.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
...@@ -11,6 +12,7 @@ import org.springframework.cache.Cache; ...@@ -11,6 +12,7 @@ import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager; import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.List; import java.util.List;
...@@ -35,20 +37,25 @@ public class EhcacheService { ...@@ -35,20 +37,25 @@ public class EhcacheService {
@Autowired @Autowired
private ImConversationMembersService imConversationMembersService; private ImConversationMembersService imConversationMembersService;
@Autowired
private RedisUtils redisUtils;
/** /**
* 本地缓存中获取 * 缓存中获取
* *
* @param key * @param key
* @return * @return
*/ */
public Boolean getIsPush(String key) { public Boolean getIsPush(String key) {
try { try {
Cache cache = cacheManager.getCache("push"); String value = redisUtils.getKey(key);
String value = cache.get(key, String.class);
if (StringUtils.isNotBlank(value)) { if (StringUtils.isNotBlank(value)) {
// 缓存中有数据 不做系统消息推送
return false; return false;
} else { } else {
cache.put(key, "1"); // 缓存中无数据, 设置缓存 3分钟, 并且需要推送
redisUtils.addKey(key, "1", Duration.ofMinutes(3));
return true; return true;
} }
} catch (Exception e) { } catch (Exception e) {
......
...@@ -13,6 +13,7 @@ import com.wecloud.im.service.ImInboxService; ...@@ -13,6 +13,7 @@ import com.wecloud.im.service.ImInboxService;
import com.wecloud.im.vo.ConversationCountVo; import com.wecloud.im.vo.ConversationCountVo;
import io.geekidea.springbootplus.framework.common.service.impl.BaseServiceImpl; import io.geekidea.springbootplus.framework.common.service.impl.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
...@@ -68,10 +69,17 @@ public class ImInboxServiceImpl extends BaseServiceImpl<ImInboxMapper, ImInbox> ...@@ -68,10 +69,17 @@ public class ImInboxServiceImpl extends BaseServiceImpl<ImInboxMapper, ImInbox>
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Boolean updateImMsgRead(MsgReadStatusUpdateParam msgReadStatusUpdateParam) { public Boolean updateImMsgRead(MsgReadStatusUpdateParam param) {
ImClient currentClient = imClientService.getCurrentClient(); ImClient currentClient = imClientService.getCurrentClient();
// 修改已读状态 // 修改已读状态
imInboxMapper.updateImMsgReadByIds(currentClient.getId(), msgReadStatusUpdateParam.getMsgIds()); LambdaQueryWrapper<ImInbox> wrapper = new QueryWrapper<ImInbox>().lambda()
.eq(ImInbox::getFkConversationId, param.getConversationId())
.eq(ImInbox::getReceiver, currentClient.getId());
if (CollectionUtils.isEmpty(param.getMsgIds())) {
return true;
}
wrapper.in(ImInbox::getFkMsgId, param.getMsgIds());
this.remove(wrapper);
return true; return true;
} }
......
...@@ -30,6 +30,12 @@ public class ChannelManager { ...@@ -30,6 +30,12 @@ public class ChannelManager {
public static final Map<String, ClientInfo> SESSION_INFO_MAP = new ConcurrentHashMap<>(); public static final Map<String, ClientInfo> SESSION_INFO_MAP = new ConcurrentHashMap<>();
/** /**
* 在线用户map 用于控制inbox表插入
* key: clientId
* value: 当天接收消息数量
*/
public static final Map<String, Integer> ONLINE_USER_MAP = new ConcurrentHashMap<>();
/**
* CLIENT_ID,是客户端的字符串id * CLIENT_ID,是客户端的字符串id
*/ */
public static final AttributeKey<Long> CLIENT_ID = AttributeKey.valueOf("ci"); public static final AttributeKey<Long> CLIENT_ID = AttributeKey.valueOf("ci");
...@@ -62,6 +68,7 @@ public class ChannelManager { ...@@ -62,6 +68,7 @@ public class ChannelManager {
String longChannelId = channel.id().asLongText(); String longChannelId = channel.id().asLongText();
log.info("保存本地连接clientId {} platform {}", clientId, platform); log.info("保存本地连接clientId {} platform {}", clientId, platform);
this.putSessionInfoMap(clientId, platform, channel); this.putSessionInfoMap(clientId, platform, channel);
ChannelManager.ONLINE_USER_MAP.put(String.valueOf(clientId), 1);
UserStateListener.triggerOnlineEvent(clientId, platform, longChannelId); UserStateListener.triggerOnlineEvent(clientId, platform, longChannelId);
} }
...@@ -90,6 +97,7 @@ public class ChannelManager { ...@@ -90,6 +97,7 @@ public class ChannelManager {
// 移除本地维护的channel // 移除本地维护的channel
delSessionInfoMap(clientId, platform); delSessionInfoMap(clientId, platform);
ChannelManager.ONLINE_USER_MAP.remove(String.valueOf(clientId));
UserStateListener.triggerOfflineEvent(clientId, platform, longChannelId); UserStateListener.triggerOfflineEvent(clientId, platform, longChannelId);
} }
......
...@@ -134,9 +134,8 @@ public class ChannelSender { ...@@ -134,9 +134,8 @@ public class ChannelSender {
public Boolean sendMsg(WsResponse responseModel, Long toClientId) { public Boolean sendMsg(WsResponse responseModel, Long toClientId) {
String msgJson = JsonUtils.encodeJson(responseModel); String msgJson = JsonUtils.encodeJson(responseModel);
List<ClientChannelInfo> channelInfos = userStateCacheManager.findOnlineInfosByClientId(toClientId); List<ClientChannelInfo> channelInfos = userStateCacheManager.findOnlineInfosByClientId(toClientId);
// log.info("获取在线用户入参 {}, 结果 {}", toClientId, JSON.toJSONString(channelInfos)); // log.info("获取在线用户耗时 {} 内容 {}", System.currentTimeMillis() - time1, JSON.toJSONString(channelInfos));
if (CollectionUtils.isEmpty(channelInfos)) { if (CollectionUtils.isEmpty(channelInfos)) {
return false; return false;
......
...@@ -16,14 +16,11 @@ ...@@ -16,14 +16,11 @@
package io.geekidea.springbootplus.framework.common.api; package io.geekidea.springbootplus.framework.common.api;
import io.geekidea.springbootplus.framework.config.il8n.I18nMessageUtil;
import io.geekidea.springbootplus.framework.config.il8n.LanguageEnum;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
...@@ -85,29 +82,10 @@ public class ApiResult<T> implements Serializable { ...@@ -85,29 +82,10 @@ public class ApiResult<T> implements Serializable {
public static <T> ApiResult<T> result(ApiCode apiCode, String message, T data) { public static <T> ApiResult<T> result(ApiCode apiCode, String message, T data) {
// boolean success = false;
// if (apiCode.getCode() == ApiCode.SUCCESS.getCode()) {
// success = true;
// }
// 多语言国际化,根据http上下文, 取得heard中的language语言属性,实现不用在业务代码中传递语言字段
// HttpServletRequest request = HttpServletRequestUtil.getRequest();
// String language = request.getHeader("language");
String success = "SUCCESS";
try {
message = I18nMessageUtil.getMessage(LanguageEnum.getLanguageType(null), apiCode.getMessage(), success);
} catch (IOException e) {
message = success;
}
return (ApiResult<T>) ApiResult.builder() return (ApiResult<T>) ApiResult.builder()
.code(apiCode.getCode()) .code(apiCode.getCode())
.message(message) .message(message)
.data(data) .data(data)
// .success(success)
// .time(new Date())
.build(); .build();
} }
......
package io.geekidea.springbootplus.framework.config.il8n;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import java.io.IOException;
/**
* 多语言国际化消息工具类
*/
public class I18nMessageUtil {
// 根目录
private static final String PATH_PARENT = "classpath:static/i18n/messages_";
// 后缀
private static final String SUFFIX = ".properties";
// 分解器
private static final ResourcePatternResolver RESOURCE_PATTERN_RESOLVER = new PathMatchingResourcePatternResolver();
// 存取器
private static MessageSourceAccessor accessor;
private I18nMessageUtil() {
}
/**
* 初始化资源文件的存储器
* 加载指定语言配置文件
*
* @param language 语言类型(文件名即为语言类型,eg: en_us 表明使用 美式英文 语言配置)
*/
private static void initMessageSourceAccessor(String language) throws IOException {
/*
* 获取配置文件名
*/
Resource resource = RESOURCE_PATTERN_RESOLVER.getResource(PATH_PARENT + language + SUFFIX);
String fileName = resource.getURL().toString();
int lastIndex = fileName.lastIndexOf(".");
String baseName = fileName.substring(0, lastIndex);
/*
* 读取配置文件
*/
ReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource = new ReloadableResourceBundleMessageSource();
reloadableResourceBundleMessageSource.setBasename(baseName);
reloadableResourceBundleMessageSource.setCacheSeconds(5);
reloadableResourceBundleMessageSource.setDefaultEncoding("UTF-8");
accessor = new MessageSourceAccessor(reloadableResourceBundleMessageSource);
}
/**
* 获取一条语言配置信息
*
* @param language 语言类型,zh_CN: 简体中文, en_US: 英文
* @param message 配置信息属性名,eg: api.response.code.user.signUp
* @param defaultMessage 默认信息,当无法从配置文件中读取到对应的配置信息时返回该信息
* @return
* @throws IOException
*/
public static String getMessage(String language, String message, String defaultMessage) throws IOException {
initMessageSourceAccessor(language);
return accessor.getMessage(message, defaultMessage, LocaleContextHolder.getLocale());
}
}
package io.geekidea.springbootplus.framework.config.il8n;
import lombok.Getter;
import lombok.ToString;
import org.springframework.util.StringUtils;
/**
* 语言枚举类
*/
@Getter
@ToString
public enum LanguageEnum {
/**
* 美式英文
*/
LANGUAGE_EN_US("en_US"),
// /**
// * 柬埔寨 高棉语
// */
// LANGUAGE_KH("kh"),
/**
* 简体中文
*/
LANGUAGE_ZH_CN("zh_CN");
private final String language;
LanguageEnum(String language) {
this.language = language;
}
/**
* 获取指定语言类型(如果没有对应的语言类型,则返回中文)
*
* @param language 语言类型
* @return
*/
public static String getLanguageType(String language) {
// 设置默认为中文
if (StringUtils.isEmpty(language)) {
return LANGUAGE_ZH_CN.language;
}
for (LanguageEnum languageEnum : LanguageEnum.values()) {
if (languageEnum.language.equalsIgnoreCase(language)) {
return languageEnum.language;
}
}
return LANGUAGE_ZH_CN.language;
}
}
...@@ -30,23 +30,16 @@ public class MessageScheduled { ...@@ -30,23 +30,16 @@ public class MessageScheduled {
/** /**
* 离线消息处理定时器 * 离线消息处理定时器
* 15之前的离线消息直接删除 * 7之前的离线消息直接删除
* 一星期前的已读消息 删除
* 一天执行一次 凌晨3点执行 * 一天执行一次 凌晨3点执行
*/ */
@Scheduled(cron = "0 0 3 * * ?") @Scheduled(cron = "0 0 3 * * ?")
public void inboxDelete() { public void inboxDelete() {
log.info("离线消息处理定时器处理开始..."); log.info("离线消息处理定时器处理开始...");
// 15天之前数据, 直接删除 // 7天之前数据, 直接删除
Date allDeleteTime = DateUtils.addDays(new Date(), -15); Date allDeleteTime = DateUtils.addDays(new Date(), -7);
imInboxService.remove(new QueryWrapper<ImInbox>().lambda() imInboxService.remove(new QueryWrapper<ImInbox>().lambda()
.lt(ImInbox::getCreateTime, allDeleteTime)); .lt(ImInbox::getCreateTime, allDeleteTime));
// 7天之前数据, 删除已读消息
Date readTime = DateUtils.addDays(new Date(), -7);
imInboxService.remove(new QueryWrapper<ImInbox>().lambda()
.eq(ImInbox::getReadMsgStatus, 1)
.lt(ImInbox::getCreateTime, readTime));
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment