Browse Source

代码风格优化(阿里规约)

master
xsx 2 years ago
parent
commit
cf09ab1b07
  1. 1
      im-client/src/main/java/com/bx/imclient/IMClient.java
  2. 9
      im-client/src/main/java/com/bx/imclient/config/RedisConfig.java
  3. 12
      im-client/src/main/java/com/bx/imclient/sender/IMSender.java
  4. 3
      im-client/src/main/java/com/bx/imclient/task/AbstractMessageResultTask.java
  5. 2
      im-client/src/main/java/com/bx/imclient/task/GroupMessageResultResultTask.java
  6. 2
      im-client/src/main/java/com/bx/imclient/task/PrivateMessageResultResultTask.java
  7. 4
      im-commom/src/main/java/com/bx/imcommon/enums/IMCmdType.java
  8. 4
      im-commom/src/main/java/com/bx/imcommon/enums/IMListenerType.java
  9. 17
      im-commom/src/main/java/com/bx/imcommon/enums/IMSendCode.java
  10. 4
      im-commom/src/main/java/com/bx/imcommon/enums/IMTerminalType.java
  11. 3
      im-commom/src/main/java/com/bx/imcommon/model/IMGroupMessage.java
  12. 10
      im-commom/src/main/java/com/bx/imcommon/model/IMRecvInfo.java
  13. 4
      im-commom/src/main/java/com/bx/imcommon/model/IMSendInfo.java
  14. 4
      im-commom/src/main/java/com/bx/imcommon/model/IMSendResult.java
  15. 5
      im-commom/src/main/java/com/bx/imcommon/model/IMSessionInfo.java
  16. 2
      im-commom/src/main/java/com/bx/imcommon/model/IMUserInfo.java
  17. 28
      im-commom/src/main/java/com/bx/imcommon/util/JwtUtil.java
  18. 1
      im-platform/src/main/java/com/bx/implatform/config/GlobalCorsConfig.java
  19. 6
      im-platform/src/main/java/com/bx/implatform/config/ICEServer.java
  20. 19
      im-platform/src/main/java/com/bx/implatform/config/MvcConfig.java
  21. 1
      im-platform/src/main/java/com/bx/implatform/controller/FileController.java
  22. 1
      im-platform/src/main/java/com/bx/implatform/controller/FriendController.java
  23. 3
      im-platform/src/main/java/com/bx/implatform/controller/GroupController.java
  24. 7
      im-platform/src/main/java/com/bx/implatform/controller/GroupMessageController.java
  25. 6
      im-platform/src/main/java/com/bx/implatform/controller/LoginController.java
  26. 6
      im-platform/src/main/java/com/bx/implatform/controller/PrivateMessageController.java
  27. 1
      im-platform/src/main/java/com/bx/implatform/controller/UserController.java
  28. 1
      im-platform/src/main/java/com/bx/implatform/controller/WebrtcController.java
  29. 11
      im-platform/src/main/java/com/bx/implatform/interceptor/AuthInterceptor.java
  30. 3
      im-platform/src/main/java/com/bx/implatform/interceptor/XssInterceptor.java
  31. 3
      im-platform/src/main/java/com/bx/implatform/listener/GroupMessageListener.java
  32. 3
      im-platform/src/main/java/com/bx/implatform/listener/PrivateMessageListener.java
  33. 36
      im-platform/src/main/java/com/bx/implatform/result/ResultUtils.java
  34. 4
      im-platform/src/main/java/com/bx/implatform/service/IGroupMessageService.java
  35. 4
      im-platform/src/main/java/com/bx/implatform/service/IPrivateMessageService.java
  36. 4
      im-platform/src/main/java/com/bx/implatform/service/IUserService.java
  37. 1
      im-platform/src/main/java/com/bx/implatform/service/IWebrtcService.java
  38. 5
      im-platform/src/main/java/com/bx/implatform/service/impl/GroupMemberServiceImpl.java
  39. 69
      im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java
  40. 146
      im-platform/src/main/java/com/bx/implatform/service/impl/GroupServiceImpl.java
  41. 12
      im-platform/src/main/java/com/bx/implatform/service/impl/PrivateMessageServiceImpl.java
  42. 100
      im-platform/src/main/java/com/bx/implatform/service/impl/UserServiceImpl.java
  43. 8
      im-platform/src/main/java/com/bx/implatform/service/impl/WebrtcServiceImpl.java
  44. 21
      im-platform/src/main/java/com/bx/implatform/service/thirdparty/FileService.java
  45. 2
      im-platform/src/main/java/com/bx/implatform/session/WebrtcSession.java
  46. 133
      im-platform/src/main/java/com/bx/implatform/util/BeanUtils.java
  47. 18
      im-platform/src/main/java/com/bx/implatform/util/DateTimeUtils.java
  48. 3
      im-platform/src/main/java/com/bx/implatform/util/FileUtil.java
  49. 58
      im-platform/src/main/java/com/bx/implatform/util/MinioUtil.java
  50. 4
      im-platform/src/main/java/com/bx/implatform/util/XssUtil.java
  51. 1
      im-platform/src/main/java/com/bx/implatform/vo/GroupVO.java
  52. 14
      im-server/src/main/java/com/bx/imserver/config/RedisConfig.java
  53. 23
      im-server/src/main/java/com/bx/imserver/netty/IMChannelHandler.java
  54. 1
      im-server/src/main/java/com/bx/imserver/netty/IMServerGroup.java
  55. 1
      im-server/src/main/java/com/bx/imserver/netty/UserChannelCtxMap.java
  56. 5
      im-server/src/main/java/com/bx/imserver/netty/processor/GroupMessageProcessor.java
  57. 11
      im-server/src/main/java/com/bx/imserver/netty/processor/HeartbeatProcessor.java
  58. 11
      im-server/src/main/java/com/bx/imserver/netty/processor/LoginProcessor.java
  59. 9
      im-server/src/main/java/com/bx/imserver/netty/processor/PrivateMessageProcessor.java
  60. 8
      im-server/src/main/java/com/bx/imserver/netty/processor/ProcessorFactory.java
  61. 7
      im-server/src/main/java/com/bx/imserver/netty/ws/WebSocketServer.java
  62. 1
      im-server/src/main/java/com/bx/imserver/netty/ws/endecode/MessageProtocolEncoder.java
  63. 4
      im-server/src/main/java/com/bx/imserver/task/AbstractPullMessageTask.java
  64. 7
      im-server/src/main/java/com/bx/imserver/task/PullGroupMessageTask.java
  65. 9
      im-server/src/main/java/com/bx/imserver/task/PullPrivateMessageTask.java

1
im-client/src/main/java/com/bx/imclient/IMClient.java

@ -5,7 +5,6 @@ import com.bx.imcommon.enums.IMTerminalType;
import com.bx.imcommon.model.IMGroupMessage; import com.bx.imcommon.model.IMGroupMessage;
import com.bx.imcommon.model.IMPrivateMessage; import com.bx.imcommon.model.IMPrivateMessage;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import java.util.List; import java.util.List;

9
im-client/src/main/java/com/bx/imclient/config/RedisConfig.java

@ -1,21 +1,12 @@
package com.bx.imclient.config; package com.bx.imclient.config;
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer; import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer;
import javax.annotation.Resource;
@Configuration("IMRedisConfig") @Configuration("IMRedisConfig")
public class RedisConfig { public class RedisConfig {

12
im-client/src/main/java/com/bx/imclient/sender/IMSender.java

@ -8,23 +8,21 @@ import com.bx.imcommon.enums.IMListenerType;
import com.bx.imcommon.enums.IMSendCode; import com.bx.imcommon.enums.IMSendCode;
import com.bx.imcommon.enums.IMTerminalType; import com.bx.imcommon.enums.IMTerminalType;
import com.bx.imcommon.model.*; import com.bx.imcommon.model.*;
import lombok.AllArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*; import java.util.*;
@Service @Service
@AllArgsConstructor @RequiredArgsConstructor
public class IMSender { public class IMSender {
@Autowired @Resource(name="IMRedisTemplate")
@Qualifier("IMRedisTemplate")
private RedisTemplate<String, Object> redisTemplate; private RedisTemplate<String, Object> redisTemplate;
private MessageListenerMulticaster listenerMulticaster; private final MessageListenerMulticaster listenerMulticaster;
public<T> void sendPrivateMessage(IMPrivateMessage<T> message) { public<T> void sendPrivateMessage(IMPrivateMessage<T> message) {
for (Integer terminal : message.getRecvTerminals()) { for (Integer terminal : message.getRecvTerminals()) {

3
im-client/src/main/java/com/bx/imclient/task/AbstractMessageResultTask.java

@ -5,7 +5,8 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner; import org.springframework.boot.CommandLineRunner;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import java.util.concurrent.*; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Slf4j @Slf4j
public abstract class AbstractMessageResultTask implements CommandLineRunner { public abstract class AbstractMessageResultTask implements CommandLineRunner {

2
im-client/src/main/java/com/bx/imclient/task/GroupMessageResultResultTask.java

@ -6,8 +6,6 @@ import com.bx.imcommon.contant.IMRedisKey;
import com.bx.imcommon.enums.IMListenerType; import com.bx.imcommon.enums.IMListenerType;
import com.bx.imcommon.model.IMSendResult; import com.bx.imcommon.model.IMSendResult;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;

2
im-client/src/main/java/com/bx/imclient/task/PrivateMessageResultResultTask.java

@ -7,8 +7,6 @@ import com.bx.imcommon.enums.IMListenerType;
import com.bx.imcommon.model.IMSendResult; import com.bx.imcommon.model.IMSendResult;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;

4
im-commom/src/main/java/com/bx/imcommon/enums/IMCmdType.java

@ -13,9 +13,9 @@ public enum IMCmdType {
GROUP_MESSAGE(4,"群发消息"); GROUP_MESSAGE(4,"群发消息");
private Integer code; private final Integer code;
private String desc; private final String desc;
public static IMCmdType fromCode(Integer code){ public static IMCmdType fromCode(Integer code){

4
im-commom/src/main/java/com/bx/imcommon/enums/IMListenerType.java

@ -8,9 +8,9 @@ public enum IMListenerType{
PRIVATE_MESSAGE(1,"私聊消息"), PRIVATE_MESSAGE(1,"私聊消息"),
GROUP_MESSAGE(2,"群聊消息"); GROUP_MESSAGE(2,"群聊消息");
private Integer code; private final Integer code;
private String desc; private final String desc;

17
im-commom/src/main/java/com/bx/imcommon/enums/IMSendCode.java

@ -10,21 +10,8 @@ public enum IMSendCode {
NOT_FIND_CHANNEL(2,"未找到对方的channel"), NOT_FIND_CHANNEL(2,"未找到对方的channel"),
UNKONW_ERROR(9999,"未知异常"); UNKONW_ERROR(9999,"未知异常");
private Integer code; private final Integer code;
private String desc; private final String desc;
public static IMSendCode fromCode(Integer code){
for (IMSendCode typeEnum:values()) {
if (typeEnum.code.equals(code)) {
return typeEnum;
}
}
return null;
}
public Integer code(){ public Integer code(){
return this.code; return this.code;

4
im-commom/src/main/java/com/bx/imcommon/enums/IMTerminalType.java

@ -12,9 +12,9 @@ public enum IMTerminalType {
WEB(0,"web"), WEB(0,"web"),
APP(1,"app"); APP(1,"app");
private Integer code; private final Integer code;
private String desc; private final String desc;
public static IMTerminalType fromCode(Integer code){ public static IMTerminalType fromCode(Integer code){

3
im-commom/src/main/java/com/bx/imcommon/model/IMGroupMessage.java

@ -3,7 +3,6 @@ package com.bx.imcommon.model;
import com.bx.imcommon.enums.IMTerminalType; import com.bx.imcommon.enums.IMTerminalType;
import lombok.Data; import lombok.Data;
import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -18,7 +17,7 @@ public class IMGroupMessage<T> {
/** /**
* 接收者id列表(群成员列表,为空则不会推送) * 接收者id列表(群成员列表,为空则不会推送)
*/ */
private List<Long> recvIds = Collections.EMPTY_LIST; private List<Long> recvIds = new LinkedList<>();
/** /**

10
im-commom/src/main/java/com/bx/imcommon/model/IMRecvInfo.java

@ -7,27 +7,27 @@ import java.util.List;
@Data @Data
public class IMRecvInfo { public class IMRecvInfo {
/* /**
* 命令类型 IMCmdType * 命令类型 IMCmdType
*/ */
private Integer cmd; private Integer cmd;
/* /**
* 发送方 * 发送方
*/ */
private IMUserInfo sender; private IMUserInfo sender;
/* /**
* 接收方用户列表 * 接收方用户列表
*/ */
List<IMUserInfo> receivers; List<IMUserInfo> receivers;
/* /**
* 是否需要回调发送结果 * 是否需要回调发送结果
*/ */
private Boolean sendResult; private Boolean sendResult;
/* /**
* 推送消息体 * 推送消息体
*/ */
private Object data; private Object data;

4
im-commom/src/main/java/com/bx/imcommon/model/IMSendInfo.java

@ -5,12 +5,12 @@ import lombok.Data;
@Data @Data
public class IMSendInfo<T> { public class IMSendInfo<T> {
/* /**
* 命令 * 命令
*/ */
private Integer cmd; private Integer cmd;
/* /**
* 推送消息体 * 推送消息体
*/ */
private T data; private T data;

4
im-commom/src/main/java/com/bx/imcommon/model/IMSendResult.java

@ -15,12 +15,12 @@ public class IMSendResult<T> {
*/ */
private IMUserInfo receiver; private IMUserInfo receiver;
/* /**
* 发送状态 IMCmdType * 发送状态 IMCmdType
*/ */
private Integer code; private Integer code;
/* /**
* 消息内容 * 消息内容
*/ */
private T data; private T data;

5
im-commom/src/main/java/com/bx/imcommon/model/IMSessionInfo.java

@ -1,16 +1,15 @@
package com.bx.imcommon.model; package com.bx.imcommon.model;
import com.bx.imcommon.enums.IMTerminalType;
import lombok.Data; import lombok.Data;
@Data @Data
public class IMSessionInfo { public class IMSessionInfo {
/* /**
* 用户id * 用户id
*/ */
private Long userId; private Long userId;
/* /**
* 终端类型 * 终端类型
*/ */
private Integer terminal; private Integer terminal;

2
im-commom/src/main/java/com/bx/imcommon/model/IMUserInfo.java

@ -4,8 +4,6 @@ import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import java.util.List;
/** /**
* @author: 谢绍许 * @author: 谢绍许
* @date: 2023-09-24 09:23:11 * @date: 2023-09-24 09:23:11

28
im-commom/src/main/java/com/bx/imcommon/util/JwtUtil.java

@ -12,11 +12,11 @@ public class JwtUtil {
/** /**
* 生成jwt字符串 JWT(json web token) * 生成jwt字符串 JWT(json web token)
* @param userId * @param userId 用户id
* @param info * @param info 用户细腻系
* @param expireIn * @param expireIn 过期时间
* @param secret * @param secret 秘钥
* @return * @return token
* */ * */
public static String sign(Long userId, String info,long expireIn,String secret) { public static String sign(Long userId, String info,long expireIn,String secret) {
try { try {
@ -38,8 +38,8 @@ public class JwtUtil {
/** /**
* 根据token获取userId * 根据token获取userId
* @param token * @param token 登录token
* @return * @return 用户id
* */ * */
public static Long getUserId(String token) { public static Long getUserId(String token) {
try { try {
@ -51,9 +51,9 @@ public class JwtUtil {
} }
/** /**
* 根据token获取自定义数据info * 根据token获取用户数据
* @param token * @param token 用户登录token
* @return * @return 用户数据
* */ * */
public static String getInfo(String token) { public static String getInfo(String token) {
try { try {
@ -65,11 +65,11 @@ public class JwtUtil {
/** /**
* 校验token * 校验token
* @param token * @param token 用户登录token
* @param secret * @param secret 秘钥
* @return * @return true/false
* */ * */
public static boolean checkSign(String token,String secret) { public static Boolean checkSign(String token,String secret) {
try{ try{
Algorithm algorithm = Algorithm.HMAC256(secret); Algorithm algorithm = Algorithm.HMAC256(secret);
JWTVerifier verifier = JWT.require(algorithm).build(); JWTVerifier verifier = JWT.require(algorithm).build();

1
im-platform/src/main/java/com/bx/implatform/config/GlobalCorsConfig.java

@ -2,7 +2,6 @@ package com.bx.implatform.config;
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

6
im-platform/src/main/java/com/bx/implatform/config/ICEServer.java

@ -6,14 +6,8 @@ import lombok.Data;
@Data @Data
public class ICEServer { public class ICEServer {
private String urls; private String urls;
private String username; private String username;
private String credential; private String credential;
} }

19
im-platform/src/main/java/com/bx/implatform/config/MvcConfig.java

@ -2,6 +2,7 @@ package com.bx.implatform.config;
import com.bx.implatform.interceptor.AuthInterceptor; import com.bx.implatform.interceptor.AuthInterceptor;
import com.bx.implatform.interceptor.XssInterceptor; import com.bx.implatform.interceptor.XssInterceptor;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@ -11,30 +12,22 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration @Configuration
@AllArgsConstructor
public class MvcConfig implements WebMvcConfigurer { public class MvcConfig implements WebMvcConfigurer {
private final AuthInterceptor authInterceptor;
private final XssInterceptor xssInterceptor;
@Override @Override
public void addInterceptors(InterceptorRegistry registry) { public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(xssInterceptor()) registry.addInterceptor(xssInterceptor)
.addPathPatterns("/**"); .addPathPatterns("/**");
registry.addInterceptor(authInterceptor()) registry.addInterceptor(authInterceptor)
.addPathPatterns("/**") .addPathPatterns("/**")
.excludePathPatterns("/login","/logout","/register","/refreshToken", .excludePathPatterns("/login","/logout","/register","/refreshToken",
"/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**"); "/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**");
} }
@Bean
public AuthInterceptor authInterceptor() {
return new AuthInterceptor();
}
@Bean
public XssInterceptor xssInterceptor() {
return new XssInterceptor();
}
@Bean @Bean
public PasswordEncoder passwordEncoder(){ public PasswordEncoder passwordEncoder(){
// 使用BCrypt加密密码 // 使用BCrypt加密密码

1
im-platform/src/main/java/com/bx/implatform/controller/FileController.java

@ -8,7 +8,6 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;

1
im-platform/src/main/java/com/bx/implatform/controller/FriendController.java

@ -9,7 +9,6 @@ import com.bx.implatform.vo.FriendVO;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.validation.Valid; import javax.validation.Valid;

3
im-platform/src/main/java/com/bx/implatform/controller/GroupController.java

@ -1,6 +1,5 @@
package com.bx.implatform.controller; package com.bx.implatform.controller;
import com.bx.implatform.result.Result; import com.bx.implatform.result.Result;
import com.bx.implatform.result.ResultUtils; import com.bx.implatform.result.ResultUtils;
import com.bx.implatform.service.IGroupService; import com.bx.implatform.service.IGroupService;
@ -10,11 +9,9 @@ import com.bx.implatform.vo.GroupVO;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.validation.Valid; import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.util.List; import java.util.List;

7
im-platform/src/main/java/com/bx/implatform/controller/GroupMessageController.java

@ -1,16 +1,13 @@
package com.bx.implatform.controller; package com.bx.implatform.controller;
import com.bx.implatform.dto.GroupMessageDTO;
import com.bx.implatform.vo.GroupMessageVO;
import com.bx.implatform.result.Result; import com.bx.implatform.result.Result;
import com.bx.implatform.result.ResultUtils; import com.bx.implatform.result.ResultUtils;
import com.bx.implatform.service.IGroupMessageService; import com.bx.implatform.service.IGroupMessageService;
import com.bx.implatform.dto.GroupMessageDTO; import com.bx.implatform.vo.GroupMessageVO;
import com.bx.implatform.vo.PrivateMessageVO;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.validation.Valid; import javax.validation.Valid;

6
im-platform/src/main/java/com/bx/implatform/controller/LoginController.java

@ -1,17 +1,15 @@
package com.bx.implatform.controller; package com.bx.implatform.controller;
import com.bx.implatform.dto.LoginDTO;
import com.bx.implatform.dto.ModifyPwdDTO; import com.bx.implatform.dto.ModifyPwdDTO;
import com.bx.implatform.dto.RegisterDTO;
import com.bx.implatform.result.Result; import com.bx.implatform.result.Result;
import com.bx.implatform.result.ResultUtils; import com.bx.implatform.result.ResultUtils;
import com.bx.implatform.service.IUserService; import com.bx.implatform.service.IUserService;
import com.bx.implatform.dto.LoginDTO;
import com.bx.implatform.dto.RegisterDTO;
import com.bx.implatform.vo.LoginVO; import com.bx.implatform.vo.LoginVO;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.validation.Valid; import javax.validation.Valid;

6
im-platform/src/main/java/com/bx/implatform/controller/PrivateMessageController.java

@ -1,15 +1,13 @@
package com.bx.implatform.controller; package com.bx.implatform.controller;
import com.bx.implatform.dto.PrivateMessageDTO;
import com.bx.implatform.vo.PrivateMessageVO;
import com.bx.implatform.result.Result; import com.bx.implatform.result.Result;
import com.bx.implatform.result.ResultUtils; import com.bx.implatform.result.ResultUtils;
import com.bx.implatform.service.IPrivateMessageService; import com.bx.implatform.service.IPrivateMessageService;
import com.bx.implatform.dto.PrivateMessageDTO; import com.bx.implatform.vo.PrivateMessageVO;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.validation.Valid; import javax.validation.Valid;

1
im-platform/src/main/java/com/bx/implatform/controller/UserController.java

@ -12,7 +12,6 @@ import com.bx.implatform.vo.UserVO;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.validation.Valid; import javax.validation.Valid;

1
im-platform/src/main/java/com/bx/implatform/controller/WebrtcController.java

@ -7,7 +7,6 @@ import com.bx.implatform.service.IWebrtcService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List; import java.util.List;

11
im-platform/src/main/java/com/bx/implatform/interceptor/AuthInterceptor.java

@ -1,26 +1,27 @@
package com.bx.implatform.interceptor; package com.bx.implatform.interceptor;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.bx.imcommon.util.JwtUtil;
import com.bx.implatform.config.JwtProperties; import com.bx.implatform.config.JwtProperties;
import com.bx.implatform.enums.ResultCode; import com.bx.implatform.enums.ResultCode;
import com.bx.implatform.exception.GlobalException; import com.bx.implatform.exception.GlobalException;
import com.bx.implatform.session.UserSession; import com.bx.implatform.session.UserSession;
import com.bx.imcommon.util.JwtUtil;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@Slf4j @Slf4j
@Component
@AllArgsConstructor
public class AuthInterceptor implements HandlerInterceptor { public class AuthInterceptor implements HandlerInterceptor {
@Autowired private final JwtProperties jwtProperties;
private JwtProperties jwtProperties;
@Override @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

3
im-platform/src/main/java/com/bx/implatform/interceptor/XssInterceptor.java

@ -5,6 +5,7 @@ import com.bx.implatform.exception.GlobalException;
import com.bx.implatform.util.XssUtil; import com.bx.implatform.util.XssUtil;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -13,9 +14,9 @@ import java.io.BufferedReader;
import java.util.Map; import java.util.Map;
@Slf4j @Slf4j
@Component
public class XssInterceptor implements HandlerInterceptor { public class XssInterceptor implements HandlerInterceptor {
@Override @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// 检查参数 // 检查参数

3
im-platform/src/main/java/com/bx/implatform/listener/GroupMessageListener.java

@ -4,12 +4,11 @@ import com.bx.imclient.annotation.IMListener;
import com.bx.imclient.listener.MessageListener; import com.bx.imclient.listener.MessageListener;
import com.bx.imcommon.enums.IMListenerType; import com.bx.imcommon.enums.IMListenerType;
import com.bx.imcommon.enums.IMSendCode; import com.bx.imcommon.enums.IMSendCode;
import com.bx.implatform.vo.GroupMessageVO;
import com.bx.imcommon.model.IMSendResult; import com.bx.imcommon.model.IMSendResult;
import com.bx.implatform.contant.RedisKey; import com.bx.implatform.contant.RedisKey;
import com.bx.implatform.vo.GroupMessageVO;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;

3
im-platform/src/main/java/com/bx/implatform/listener/PrivateMessageListener.java

@ -5,12 +5,11 @@ import com.bx.imclient.annotation.IMListener;
import com.bx.imclient.listener.MessageListener; import com.bx.imclient.listener.MessageListener;
import com.bx.imcommon.enums.IMListenerType; import com.bx.imcommon.enums.IMListenerType;
import com.bx.imcommon.enums.IMSendCode; import com.bx.imcommon.enums.IMSendCode;
import com.bx.implatform.vo.PrivateMessageVO;
import com.bx.imcommon.model.IMSendResult; import com.bx.imcommon.model.IMSendResult;
import com.bx.implatform.entity.PrivateMessage; import com.bx.implatform.entity.PrivateMessage;
import com.bx.implatform.enums.MessageStatus; import com.bx.implatform.enums.MessageStatus;
import com.bx.implatform.service.IPrivateMessageService; import com.bx.implatform.service.IPrivateMessageService;
import lombok.AllArgsConstructor; import com.bx.implatform.vo.PrivateMessageVO;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;

36
im-platform/src/main/java/com/bx/implatform/result/ResultUtils.java

@ -5,61 +5,53 @@ import com.bx.implatform.enums.ResultCode;
public class ResultUtils { public class ResultUtils {
public static final <T> Result<T> success(){ public static <T> Result<T> success(){
Result result=new Result(); Result<T> result=new Result<>();
result.setCode(ResultCode.SUCCESS.getCode()); result.setCode(ResultCode.SUCCESS.getCode());
result.setMessage(ResultCode.SUCCESS.getMsg()); result.setMessage(ResultCode.SUCCESS.getMsg());
return result; return result;
} }
public static final <T> Result<T> success(T data){ public static <T> Result<T> success(T data){
Result result=new Result(); Result<T> result=new Result<>();
result.setCode(ResultCode.SUCCESS.getCode()); result.setCode(ResultCode.SUCCESS.getCode());
result.setMessage(ResultCode.SUCCESS.getMsg()); result.setMessage(ResultCode.SUCCESS.getMsg());
result.setData(data); result.setData(data);
return result; return result;
} }
public static final <T> Result<T> success(T data, String messsage){ public static <T> Result<T> success(T data, String messsage){
Result result=new Result(); Result<T> result=new Result<>();
result.setCode(ResultCode.SUCCESS.getCode()); result.setCode(ResultCode.SUCCESS.getCode());
result.setMessage(messsage); result.setMessage(messsage);
result.setData(data); result.setData(data);
return result; return result;
} }
public static final <T> Result<T> success(String messsage){ public static <T> Result<T> success(String messsage){
Result result=new Result(); Result<T> result=new Result<>();
result.setCode(ResultCode.SUCCESS.getCode()); result.setCode(ResultCode.SUCCESS.getCode());
result.setMessage(messsage); result.setMessage(messsage);
return result; return result;
} }
public static final <T> Result<T> error(Integer code, String messsage){ public static <T> Result<T> error(Integer code, String messsage){
Result result=new Result(); Result<T> result=new Result<>();
result.setCode(code); result.setCode(code);
result.setMessage(messsage); result.setMessage(messsage);
return result; return result;
} }
public static final <T> Result<T> error(ResultCode resultCode, String messsage){ public static <T> Result<T> error(ResultCode resultCode, String messsage){
Result result=new Result(); Result<T> result=new Result<>();
result.setCode(resultCode.getCode()); result.setCode(resultCode.getCode());
result.setMessage(messsage); result.setMessage(messsage);
return result; return result;
} }
public static final <T> Result<T> error(ResultCode resultCode, String messsage, T data){ public static <T> Result<T> error(ResultCode resultCode){
Result result=new Result(); Result<T> result=new Result<>();
result.setCode(resultCode.getCode());
result.setMessage(messsage);
result.setData(data);
return result;
}
public static final <T> Result<T> error(ResultCode resultCode){
Result result=new Result();
result.setCode(resultCode.getCode()); result.setCode(resultCode.getCode());
result.setMessage(resultCode.getMsg()); result.setMessage(resultCode.getMsg());
return result; return result;

4
im-platform/src/main/java/com/bx/implatform/service/IGroupMessageService.java

@ -1,9 +1,9 @@
package com.bx.implatform.service; package com.bx.implatform.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.bx.implatform.vo.GroupMessageVO;
import com.bx.implatform.entity.GroupMessage;
import com.bx.implatform.dto.GroupMessageDTO; import com.bx.implatform.dto.GroupMessageDTO;
import com.bx.implatform.entity.GroupMessage;
import com.bx.implatform.vo.GroupMessageVO;
import java.util.List; import java.util.List;

4
im-platform/src/main/java/com/bx/implatform/service/IPrivateMessageService.java

@ -1,9 +1,9 @@
package com.bx.implatform.service; package com.bx.implatform.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.bx.implatform.vo.PrivateMessageVO;
import com.bx.implatform.entity.PrivateMessage;
import com.bx.implatform.dto.PrivateMessageDTO; import com.bx.implatform.dto.PrivateMessageDTO;
import com.bx.implatform.entity.PrivateMessage;
import com.bx.implatform.vo.PrivateMessageVO;
import java.util.List; import java.util.List;

4
im-platform/src/main/java/com/bx/implatform/service/IUserService.java

@ -1,10 +1,10 @@
package com.bx.implatform.service; package com.bx.implatform.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.bx.implatform.dto.ModifyPwdDTO;
import com.bx.implatform.entity.User;
import com.bx.implatform.dto.LoginDTO; import com.bx.implatform.dto.LoginDTO;
import com.bx.implatform.dto.ModifyPwdDTO;
import com.bx.implatform.dto.RegisterDTO; import com.bx.implatform.dto.RegisterDTO;
import com.bx.implatform.entity.User;
import com.bx.implatform.vo.LoginVO; import com.bx.implatform.vo.LoginVO;
import com.bx.implatform.vo.OnlineTerminalVO; import com.bx.implatform.vo.OnlineTerminalVO;
import com.bx.implatform.vo.UserVO; import com.bx.implatform.vo.UserVO;

1
im-platform/src/main/java/com/bx/implatform/service/IWebrtcService.java

@ -2,6 +2,7 @@ package com.bx.implatform.service;
import com.bx.implatform.config.ICEServer; import com.bx.implatform.config.ICEServer;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import java.util.List; import java.util.List;

5
im-platform/src/main/java/com/bx/implatform/service/impl/GroupMemberServiceImpl.java

@ -21,17 +21,12 @@ import java.util.stream.Collectors;
@Service @Service
@CacheConfig(cacheNames = RedisKey.IM_CACHE_GROUP_MEMBER_ID) @CacheConfig(cacheNames = RedisKey.IM_CACHE_GROUP_MEMBER_ID)
public class GroupMemberServiceImpl extends ServiceImpl<GroupMemberMapper, GroupMember> implements IGroupMemberService { public class GroupMemberServiceImpl extends ServiceImpl<GroupMemberMapper, GroupMember> implements IGroupMemberService {
@CacheEvict(key="#member.getGroupId()") @CacheEvict(key="#member.getGroupId()")
@Override @Override
public boolean save(GroupMember member) { public boolean save(GroupMember member) {
return super.save(member); return super.save(member);
} }
@CacheEvict(key="#groupId") @CacheEvict(key="#groupId")
@Override @Override
public boolean saveOrUpdateBatch(Long groupId,List<GroupMember> members) { public boolean saveOrUpdateBatch(Long groupId,List<GroupMember> members) {

69
im-platform/src/main/java/com/bx/implatform/service/impl/GroupMessageServiceImpl.java

@ -40,11 +40,10 @@ import java.util.stream.Collectors;
@Service @Service
@AllArgsConstructor @AllArgsConstructor
public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, GroupMessage> implements IGroupMessageService { public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, GroupMessage> implements IGroupMessageService {
private IGroupService groupService; private final IGroupService groupService;
private IGroupMemberService groupMemberService; private final IGroupMemberService groupMemberService;
private RedisTemplate<String, Object> redisTemplate; private final RedisTemplate<String, Object> redisTemplate;
private IMClient imClient; private final IMClient imClient;
@Override @Override
public Long sendMessage(GroupMessageDTO dto) { public Long sendMessage(GroupMessageDTO dto) {
@ -58,7 +57,7 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
} }
// 是否在群聊里面 // 是否在群聊里面
GroupMember member = groupMemberService.findByGroupAndUserId(dto.getGroupId(), session.getUserId()); GroupMember member = groupMemberService.findByGroupAndUserId(dto.getGroupId(), session.getUserId());
if (Objects.isNull(member)||member.getQuit()) { if (Objects.isNull(member) || member.getQuit()) {
throw new GlobalException(ResultCode.PROGRAM_ERROR, "您已不在群聊里面,无法发送消息"); throw new GlobalException(ResultCode.PROGRAM_ERROR, "您已不在群聊里面,无法发送消息");
} }
// 群聊成员列表 // 群聊成员列表
@ -70,8 +69,8 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
msg.setSendId(session.getUserId()); msg.setSendId(session.getUserId());
msg.setSendTime(new Date()); msg.setSendTime(new Date());
msg.setSendNickName(member.getAliasName()); msg.setSendNickName(member.getAliasName());
if(CollectionUtil.isNotEmpty(dto.getAtUserIds())){ if (CollectionUtil.isNotEmpty(dto.getAtUserIds())) {
msg.setAtUserIds(StrUtil.join(",",dto.getAtUserIds())); msg.setAtUserIds(StrUtil.join(",", dto.getAtUserIds()));
} }
this.save(msg); this.save(msg);
// 群发 // 群发
@ -86,7 +85,6 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
return msg.getId(); return msg.getId();
} }
@Override @Override
public void recallMessage(Long id) { public void recallMessage(Long id) {
UserSession session = SessionContext.getSession(); UserSession session = SessionContext.getSession();
@ -102,7 +100,7 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
} }
// 判断是否在群里 // 判断是否在群里
GroupMember member = groupMemberService.findByGroupAndUserId(msg.getGroupId(), session.getUserId()); GroupMember member = groupMemberService.findByGroupAndUserId(msg.getGroupId(), session.getUserId());
if (Objects.isNull(member)||member.getQuit()) { if (Objects.isNull(member) || member.getQuit()) {
throw new GlobalException(ResultCode.PROGRAM_ERROR, "您已不在群聊里面,无法撤回消息"); throw new GlobalException(ResultCode.PROGRAM_ERROR, "您已不在群聊里面,无法撤回消息");
} }
// 修改数据库 // 修改数据库
@ -135,7 +133,6 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
log.info("撤回群聊消息,发送id:{},群聊id:{},内容:{}", session.getUserId(), msg.getGroupId(), msg.getContent()); log.info("撤回群聊消息,发送id:{},群聊id:{},内容:{}", session.getUserId(), msg.getGroupId(), msg.getContent());
} }
@Override @Override
public void pullUnreadMessage() { public void pullUnreadMessage() {
UserSession session = SessionContext.getSession(); UserSession session = SessionContext.getSession();
@ -143,12 +140,10 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
for (GroupMember member : members) { for (GroupMember member : members) {
// 获取群聊已读的最大消息id,只推送未读消息 // 获取群聊已读的最大消息id,只推送未读消息
String key = String.join(":", RedisKey.IM_GROUP_READED_POSITION, member.getGroupId().toString(), session.getUserId().toString()); String key = String.join(":", RedisKey.IM_GROUP_READED_POSITION, member.getGroupId().toString(), session.getUserId().toString());
Integer maxReadedId = (Integer) redisTemplate.opsForValue().get(key); Integer maxReadedId = (Integer)redisTemplate.opsForValue().get(key);
LambdaQueryWrapper<GroupMessage> wrapper = Wrappers.lambdaQuery(); LambdaQueryWrapper<GroupMessage> wrapper = Wrappers.lambdaQuery();
wrapper.eq(GroupMessage::getGroupId, member.getGroupId()) wrapper.eq(GroupMessage::getGroupId, member.getGroupId()).gt(GroupMessage::getSendTime, member.getCreatedTime())
.gt(GroupMessage::getSendTime, member.getCreatedTime()) .ne(GroupMessage::getSendId, session.getUserId()).ne(GroupMessage::getStatus, MessageStatus.RECALL.code());
.ne(GroupMessage::getSendId, session.getUserId())
.ne(GroupMessage::getStatus, MessageStatus.RECALL.code());
if (maxReadedId != null) { if (maxReadedId != null) {
wrapper.gt(GroupMessage::getId, maxReadedId); wrapper.gt(GroupMessage::getId, maxReadedId);
} }
@ -174,43 +169,37 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
} }
@Override @Override
public List<GroupMessageVO> loadMessage(Long minId) { public List<GroupMessageVO> loadMessage(Long minId) {
UserSession session = SessionContext.getSession(); UserSession session = SessionContext.getSession();
List<GroupMember> members = groupMemberService.findByUserId(session.getUserId()); List<GroupMember> members = groupMemberService.findByUserId(session.getUserId());
List<Long> ids = members.stream().map(GroupMember::getGroupId).collect(Collectors.toList()); List<Long> ids = members.stream().map(GroupMember::getGroupId).collect(Collectors.toList());
if(CollectionUtil.isEmpty(ids)){ if (CollectionUtil.isEmpty(ids)) {
return new ArrayList<>(); return new ArrayList<>();
} }
// 只能拉取最近1个月的 // 只能拉取最近1个月的
Date minDate = DateTimeUtils.addMonths(new Date(), -1); Date minDate = DateTimeUtils.addMonths(new Date(), -1);
LambdaQueryWrapper<GroupMessage> wrapper = Wrappers.lambdaQuery(); LambdaQueryWrapper<GroupMessage> wrapper = Wrappers.lambdaQuery();
wrapper.gt(GroupMessage::getId, minId) wrapper.gt(GroupMessage::getId, minId).gt(GroupMessage::getSendTime, minDate).in(GroupMessage::getGroupId, ids)
.gt(GroupMessage::getSendTime, minDate) .ne(GroupMessage::getStatus, MessageStatus.RECALL.code()).orderByAsc(GroupMessage::getId).last("limit 100");
.in(GroupMessage::getGroupId, ids)
.ne(GroupMessage::getStatus, MessageStatus.RECALL.code())
.orderByAsc(GroupMessage::getId)
.last("limit 100");
List<GroupMessage> messages = this.list(wrapper); List<GroupMessage> messages = this.list(wrapper);
// 转成vo // 转成vo
List<GroupMessageVO> vos = messages.stream().map(m -> { List<GroupMessageVO> vos = messages.stream().map(m -> {
GroupMessageVO vo = BeanUtils.copyProperties(m, GroupMessageVO.class); GroupMessageVO vo = BeanUtils.copyProperties(m, GroupMessageVO.class);
// 被@用户列表 // 被@用户列表
List<String> atIds = Arrays.asList(StrUtil.split(m.getAtUserIds(),",")); List<String> atIds = Arrays.asList(StrUtil.split(m.getAtUserIds(), ","));
vo.setAtUserIds(atIds.stream().map(Long::parseLong).collect(Collectors.toList())); vo.setAtUserIds(atIds.stream().map(Long::parseLong).collect(Collectors.toList()));
return vo; return vo;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
// 消息状态,数据库没有存群聊的消息状态,需要从redis取 // 消息状态,数据库没有存群聊的消息状态,需要从redis取
List<String> keys = ids.stream() List<String> keys = ids.stream().map(id -> String.join(":", RedisKey.IM_GROUP_READED_POSITION, id.toString(), session.getUserId().toString()))
.map(id -> String.join(":", RedisKey.IM_GROUP_READED_POSITION, id.toString(), session.getUserId().toString())) .collect(Collectors.toList());
.collect(Collectors.toList());
List<Object> sendPos = redisTemplate.opsForValue().multiGet(keys); List<Object> sendPos = redisTemplate.opsForValue().multiGet(keys);
int idx = 0; int idx = 0;
for (Long id : ids) { for (Long id : ids) {
Object o = sendPos.get(idx); Object o = sendPos.get(idx);
Integer sendMaxId = Objects.isNull(o) ? -1 : (Integer) o; Integer sendMaxId = Objects.isNull(o) ? -1 : (Integer)o;
vos.stream().filter(vo -> vo.getGroupId().equals(id)).forEach(vo -> { vos.stream().filter(vo -> vo.getGroupId().equals(id)).forEach(vo -> {
if (vo.getId() <= sendMaxId) { if (vo.getId() <= sendMaxId) {
// 已读 // 已读
@ -225,18 +214,14 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
return vos; return vos;
} }
@Override @Override
public void readedMessage(Long groupId) { public void readedMessage(Long groupId) {
UserSession session = SessionContext.getSession(); UserSession session = SessionContext.getSession();
// 取出最后的消息id // 取出最后的消息id
LambdaQueryWrapper<GroupMessage> wrapper = Wrappers.lambdaQuery(); LambdaQueryWrapper<GroupMessage> wrapper = Wrappers.lambdaQuery();
wrapper.eq(GroupMessage::getGroupId, groupId) wrapper.eq(GroupMessage::getGroupId, groupId).orderByDesc(GroupMessage::getId).last("limit 1").select(GroupMessage::getId);
.orderByDesc(GroupMessage::getId)
.last("limit 1")
.select(GroupMessage::getId);
GroupMessage message = this.getOne(wrapper); GroupMessage message = this.getOne(wrapper);
if(Objects.isNull(message)){ if (Objects.isNull(message)) {
return; return;
} }
// 推送消息给自己的其他终端 // 推送消息给自己的其他终端
@ -252,12 +237,11 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
sendMessage.setSendResult(false); sendMessage.setSendResult(false);
imClient.sendGroupMessage(sendMessage); imClient.sendGroupMessage(sendMessage);
// 记录已读消息位置 // 记录已读消息位置
String key = StrUtil.join(":",RedisKey.IM_GROUP_READED_POSITION,groupId,session.getUserId()); String key = StrUtil.join(":", RedisKey.IM_GROUP_READED_POSITION, groupId, session.getUserId());
redisTemplate.opsForValue().set(key, message.getId()); redisTemplate.opsForValue().set(key, message.getId());
} }
@Override @Override
public List<GroupMessageVO> findHistoryMessage(Long groupId, Long page, Long size) { public List<GroupMessageVO> findHistoryMessage(Long groupId, Long page, Long size) {
page = page > 0 ? page : 1; page = page > 0 ? page : 1;
@ -271,17 +255,14 @@ public class GroupMessageServiceImpl extends ServiceImpl<GroupMessageMapper, Gro
} }
// 查询聊天记录,只查询加入群聊时间之后的消息 // 查询聊天记录,只查询加入群聊时间之后的消息
QueryWrapper<GroupMessage> wrapper = new QueryWrapper<>(); QueryWrapper<GroupMessage> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(GroupMessage::getGroupId, groupId) wrapper.lambda().eq(GroupMessage::getGroupId, groupId).gt(GroupMessage::getSendTime, member.getCreatedTime())
.gt(GroupMessage::getSendTime, member.getCreatedTime()) .ne(GroupMessage::getStatus, MessageStatus.RECALL.code()).orderByDesc(GroupMessage::getId).last("limit " + stIdx + "," + size);
.ne(GroupMessage::getStatus, MessageStatus.RECALL.code())
.orderByDesc(GroupMessage::getId)
.last("limit " + stIdx + "," + size);
List<GroupMessage> messages = this.list(wrapper); List<GroupMessage> messages = this.list(wrapper);
List<GroupMessageVO> messageInfos = messages.stream().map(m -> BeanUtils.copyProperties(m, GroupMessageVO.class)).collect(Collectors.toList()); List<GroupMessageVO> messageInfos =
messages.stream().map(m -> BeanUtils.copyProperties(m, GroupMessageVO.class)).collect(Collectors.toList());
log.info("拉取群聊记录,用户id:{},群聊id:{},数量:{}", userId, groupId, messageInfos.size()); log.info("拉取群聊记录,用户id:{},群聊id:{},数量:{}", userId, groupId, messageInfos.size());
return messageInfos; return messageInfos;
} }
} }

146
im-platform/src/main/java/com/bx/implatform/service/impl/GroupServiceImpl.java

@ -38,24 +38,22 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Slf4j @Slf4j
@CacheConfig(cacheNames = RedisKey.IM_CACHE_GROUP) @CacheConfig(cacheNames = RedisKey.IM_CACHE_GROUP)
@Service @Service
@AllArgsConstructor @AllArgsConstructor
public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements IGroupService { public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements IGroupService {
private IUserService userService; private final IUserService userService;
private IGroupMemberService groupMemberService; private final IGroupMemberService groupMemberService;
private IFriendService friendsService; private final IFriendService friendsService;
private IMClient imClient; private final IMClient imClient;
@Override @Override
public GroupVO createGroup(GroupVO vo) { public GroupVO createGroup(GroupVO vo) {
UserSession session = SessionContext.getSession(); UserSession session = SessionContext.getSession();
User user = userService.getById(session.getUserId()); User user = userService.getById(session.getUserId());
// 保存群组数据 // 保存群组数据
Group group = BeanUtils.copyProperties(vo,Group.class); Group group = BeanUtils.copyProperties(vo, Group.class);
group.setOwnerId(user.getId()); group.setOwnerId(user.getId());
this.save(group); this.save(group);
// 把群主加入群 // 把群主加入群
@ -63,18 +61,17 @@ public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements
groupMember.setGroupId(group.getId()); groupMember.setGroupId(group.getId());
groupMember.setUserId(user.getId()); groupMember.setUserId(user.getId());
groupMember.setHeadImage(user.getHeadImageThumb()); groupMember.setHeadImage(user.getHeadImageThumb());
groupMember.setAliasName(StringUtils.isEmpty(vo.getAliasName())?session.getNickName():vo.getAliasName()); groupMember.setAliasName(StringUtils.isEmpty(vo.getAliasName()) ? session.getNickName() : vo.getAliasName());
groupMember.setRemark(StringUtils.isEmpty(vo.getRemark())?group.getName():vo.getRemark()); groupMember.setRemark(StringUtils.isEmpty(vo.getRemark()) ? group.getName() : vo.getRemark());
groupMemberService.save(groupMember); groupMemberService.save(groupMember);
vo.setId(group.getId()); vo.setId(group.getId());
vo.setAliasName(groupMember.getAliasName()); vo.setAliasName(groupMember.getAliasName());
vo.setRemark(groupMember.getRemark()); vo.setRemark(groupMember.getRemark());
log.info("创建群聊,群聊id:{},群聊名称:{}",group.getId(),group.getName()); log.info("创建群聊,群聊id:{},群聊名称:{}", group.getId(), group.getName());
return vo; return vo;
} }
@CacheEvict(value = "#vo.getId()") @CacheEvict(value = "#vo.getId()")
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
@ -83,109 +80,99 @@ public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements
// 校验是不是群主,只有群主能改信息 // 校验是不是群主,只有群主能改信息
Group group = this.getById(vo.getId()); Group group = this.getById(vo.getId());
// 群主有权修改群基本信息 // 群主有权修改群基本信息
if(group.getOwnerId().equals(session.getUserId()) ){ if (group.getOwnerId().equals(session.getUserId())) {
group = BeanUtils.copyProperties(vo,Group.class); group = BeanUtils.copyProperties(vo, Group.class);
this.updateById(group); this.updateById(group);
} }
// 更新成员信息 // 更新成员信息
GroupMember member = groupMemberService.findByGroupAndUserId(vo.getId(),session.getUserId()); GroupMember member = groupMemberService.findByGroupAndUserId(vo.getId(), session.getUserId());
if(member == null){ if (member == null) {
throw new GlobalException(ResultCode.PROGRAM_ERROR,"您不是群聊的成员"); throw new GlobalException(ResultCode.PROGRAM_ERROR, "您不是群聊的成员");
} }
member.setAliasName(StringUtils.isEmpty(vo.getAliasName())?session.getNickName():vo.getAliasName()); member.setAliasName(StringUtils.isEmpty(vo.getAliasName()) ? session.getNickName() : vo.getAliasName());
member.setRemark(StringUtils.isEmpty(vo.getRemark())?group.getName():vo.getRemark()); member.setRemark(StringUtils.isEmpty(vo.getRemark()) ? group.getName() : vo.getRemark());
groupMemberService.updateById(member); groupMemberService.updateById(member);
log.info("修改群聊,群聊id:{},群聊名称:{}",group.getId(),group.getName()); log.info("修改群聊,群聊id:{},群聊名称:{}", group.getId(), group.getName());
return vo; return vo;
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@CacheEvict(value = "#groupId") @CacheEvict(value = "#groupId")
@Override @Override
public void deleteGroup(Long groupId) { public void deleteGroup(Long groupId) {
UserSession session = SessionContext.getSession(); UserSession session = SessionContext.getSession();
Group group = this.getById(groupId); Group group = this.getById(groupId);
if(!group.getOwnerId().equals(session.getUserId())){ if (!group.getOwnerId().equals(session.getUserId())) {
throw new GlobalException(ResultCode.PROGRAM_ERROR,"只有群主才有权限解除群聊"); throw new GlobalException(ResultCode.PROGRAM_ERROR, "只有群主才有权限解除群聊");
} }
// 逻辑删除群数据 // 逻辑删除群数据
group.setDeleted(true); group.setDeleted(true);
this.updateById(group); this.updateById(group);
// 删除成员数据 // 删除成员数据
groupMemberService.removeByGroupId(groupId); groupMemberService.removeByGroupId(groupId);
log.info("删除群聊,群聊id:{},群聊名称:{}",group.getId(),group.getName()); log.info("删除群聊,群聊id:{},群聊名称:{}", group.getId(), group.getName());
} }
@Override @Override
public void quitGroup(Long groupId) { public void quitGroup(Long groupId) {
Long userId = SessionContext.getSession().getUserId(); Long userId = SessionContext.getSession().getUserId();
Group group = this.getById(groupId); Group group = this.getById(groupId);
if(group.getOwnerId().equals(userId)){ if (group.getOwnerId().equals(userId)) {
throw new GlobalException(ResultCode.PROGRAM_ERROR,"您是群主,不可退出群聊"); throw new GlobalException(ResultCode.PROGRAM_ERROR, "您是群主,不可退出群聊");
} }
// 删除群聊成员 // 删除群聊成员
groupMemberService.removeByGroupAndUserId(groupId,userId); groupMemberService.removeByGroupAndUserId(groupId, userId);
log.info("退出群聊,群聊id:{},群聊名称:{},用户id:{}",group.getId(),group.getName(),userId); log.info("退出群聊,群聊id:{},群聊名称:{},用户id:{}", group.getId(), group.getName(), userId);
} }
@Override @Override
public void kickGroup(Long groupId, Long userId) { public void kickGroup(Long groupId, Long userId) {
UserSession session = SessionContext.getSession(); UserSession session = SessionContext.getSession();
Group group = this.getById(groupId); Group group = this.getById(groupId);
if(!group.getOwnerId().equals(session.getUserId()) ){ if (!group.getOwnerId().equals(session.getUserId())) {
throw new GlobalException(ResultCode.PROGRAM_ERROR,"您不是群主,没有权限踢人"); throw new GlobalException(ResultCode.PROGRAM_ERROR, "您不是群主,没有权限踢人");
} }
if(userId.equals(session.getUserId())){ if (userId.equals(session.getUserId())) {
throw new GlobalException(ResultCode.PROGRAM_ERROR,"亲,不能自己踢自己哟"); throw new GlobalException(ResultCode.PROGRAM_ERROR, "亲,不能自己踢自己哟");
} }
// 删除群聊成员 // 删除群聊成员
groupMemberService.removeByGroupAndUserId(groupId,userId); groupMemberService.removeByGroupAndUserId(groupId, userId);
log.info("踢出群聊,群聊id:{},群聊名称:{},用户id:{}",group.getId(),group.getName(),userId); log.info("踢出群聊,群聊id:{},群聊名称:{},用户id:{}", group.getId(), group.getName(), userId);
} }
@Override @Override
public GroupVO findById(Long groupId) { public GroupVO findById(Long groupId) {
UserSession session = SessionContext.getSession(); UserSession session = SessionContext.getSession();
Group group = this.getById(groupId); Group group = this.getById(groupId);
GroupMember member = groupMemberService.findByGroupAndUserId(groupId,session.getUserId()); GroupMember member = groupMemberService.findByGroupAndUserId(groupId, session.getUserId());
if(member == null){ if (member == null) {
throw new GlobalException(ResultCode.PROGRAM_ERROR,"您未加入群聊"); throw new GlobalException(ResultCode.PROGRAM_ERROR, "您未加入群聊");
} }
GroupVO vo = BeanUtils.copyProperties(group,GroupVO.class); GroupVO vo = BeanUtils.copyProperties(group, GroupVO.class);
vo.setAliasName(member.getAliasName()); vo.setAliasName(member.getAliasName());
vo.setRemark(member.getRemark()); vo.setRemark(member.getRemark());
return vo; return vo;
} }
@Cacheable(value = "#groupId") @Cacheable(value = "#groupId")
@Override @Override
public Group getById(Long groupId){ public Group getById(Long groupId) {
Group group = super.getById(groupId); Group group = super.getById(groupId);
if(group == null){ if (group == null) {
throw new GlobalException(ResultCode.PROGRAM_ERROR,"群组不存在"); throw new GlobalException(ResultCode.PROGRAM_ERROR, "群组不存在");
} }
if(group.getDeleted()){ if (group.getDeleted()) {
throw new GlobalException(ResultCode.PROGRAM_ERROR,"群组'"+group.getName()+"'已解散"); throw new GlobalException(ResultCode.PROGRAM_ERROR, "群组'" + group.getName() + "'已解散");
} }
return group; return group;
} }
@Override @Override
public List<GroupVO> findGroups() { public List<GroupVO> findGroups() {
UserSession session = SessionContext.getSession(); UserSession session = SessionContext.getSession();
// 查询当前用户的群id列表 // 查询当前用户的群id列表
List<GroupMember> groupMembers = groupMemberService.findByUserId(session.getUserId()); List<GroupMember> groupMembers = groupMemberService.findByUserId(session.getUserId());
if(groupMembers.isEmpty()){ if (groupMembers.isEmpty()) {
return new LinkedList<>(); return new LinkedList<>();
} }
// 拉取群列表 // 拉取群列表
@ -203,58 +190,55 @@ public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements
}).collect(Collectors.toList()); }).collect(Collectors.toList());
} }
@Override @Override
public void invite(GroupInviteVO vo) { public void invite(GroupInviteVO vo) {
UserSession session = SessionContext.getSession(); UserSession session = SessionContext.getSession();
Group group = this.getById(vo.getGroupId()); Group group = this.getById(vo.getGroupId());
if(group == null){ if (group == null) {
throw new GlobalException(ResultCode.PROGRAM_ERROR, "群聊不存在"); throw new GlobalException(ResultCode.PROGRAM_ERROR, "群聊不存在");
} }
// 群聊人数校验 // 群聊人数校验
List<GroupMember> members = groupMemberService.findByGroupId(vo.getGroupId()); List<GroupMember> members = groupMemberService.findByGroupId(vo.getGroupId());
long size = members.stream().filter(m->!m.getQuit()).count(); long size = members.stream().filter(m -> !m.getQuit()).count();
if(vo.getFriendIds().size() + size > Constant.MAX_GROUP_MEMBER){ if (vo.getFriendIds().size() + size > Constant.MAX_GROUP_MEMBER) {
throw new GlobalException(ResultCode.PROGRAM_ERROR, "群聊人数不能大于"+Constant.MAX_GROUP_MEMBER+"人"); throw new GlobalException(ResultCode.PROGRAM_ERROR, "群聊人数不能大于" + Constant.MAX_GROUP_MEMBER + "人");
} }
// 找出好友信息 // 找出好友信息
List<Friend> friends = friendsService.findFriendByUserId(session.getUserId()); List<Friend> friends = friendsService.findFriendByUserId(session.getUserId());
List<Friend> friendsList = vo.getFriendIds().stream().map(id -> List<Friend> friendsList = vo.getFriendIds().stream().map(id -> friends.stream().filter(f -> f.getFriendId().equals(id)).findFirst().get())
friends.stream().filter(f -> f.getFriendId().equals(id)).findFirst().get()).collect(Collectors.toList()); .collect(Collectors.toList());
if (friendsList.size() != vo.getFriendIds().size()) { if (friendsList.size() != vo.getFriendIds().size()) {
throw new GlobalException(ResultCode.PROGRAM_ERROR, "部分用户不是您的好友,邀请失败"); throw new GlobalException(ResultCode.PROGRAM_ERROR, "部分用户不是您的好友,邀请失败");
} }
// 批量保存成员数据 // 批量保存成员数据
List<GroupMember> groupMembers = friendsList.stream() List<GroupMember> groupMembers = friendsList.stream().map(f -> {
.map(f -> { Optional<GroupMember> optional = members.stream().filter(m -> m.getUserId().equals(f.getFriendId())).findFirst();
Optional<GroupMember> optional = members.stream().filter(m->m.getUserId().equals(f.getFriendId())).findFirst(); GroupMember groupMember = optional.orElseGet(GroupMember::new);
GroupMember groupMember = optional.orElseGet(GroupMember::new); groupMember.setGroupId(vo.getGroupId());
groupMember.setGroupId(vo.getGroupId()); groupMember.setUserId(f.getFriendId());
groupMember.setUserId(f.getFriendId()); groupMember.setAliasName(f.getFriendNickName());
groupMember.setAliasName(f.getFriendNickName()); groupMember.setRemark(group.getName());
groupMember.setRemark(group.getName()); groupMember.setHeadImage(f.getFriendHeadImage());
groupMember.setHeadImage(f.getFriendHeadImage()); groupMember.setCreatedTime(new Date());
groupMember.setCreatedTime(new Date()); groupMember.setQuit(false);
groupMember.setQuit(false); return groupMember;
return groupMember; }).collect(Collectors.toList());
}).collect(Collectors.toList()); if (!groupMembers.isEmpty()) {
if(!groupMembers.isEmpty()) { groupMemberService.saveOrUpdateBatch(group.getId(), groupMembers);
groupMemberService.saveOrUpdateBatch(group.getId(),groupMembers);
} }
log.info("邀请进入群聊,群聊id:{},群聊名称:{},被邀请用户id:{}",group.getId(),group.getName(),vo.getFriendIds()); log.info("邀请进入群聊,群聊id:{},群聊名称:{},被邀请用户id:{}", group.getId(), group.getName(), vo.getFriendIds());
} }
@Override @Override
public List<GroupMemberVO> findGroupMembers(Long groupId) { public List<GroupMemberVO> findGroupMembers(Long groupId) {
List<GroupMember> members = groupMemberService.findByGroupId(groupId); List<GroupMember> members = groupMemberService.findByGroupId(groupId);
List<Long> userIds = members.stream().map(GroupMember::getUserId).collect(Collectors.toList()); List<Long> userIds = members.stream().map(GroupMember::getUserId).collect(Collectors.toList());
List<Long> onlineUserIds = imClient.getOnlineUser(userIds); List<Long> onlineUserIds = imClient.getOnlineUser(userIds);
return members.stream().map(m->{ return members.stream().map(m -> {
GroupMemberVO vo = BeanUtils.copyProperties(m,GroupMemberVO.class); GroupMemberVO vo = BeanUtils.copyProperties(m, GroupMemberVO.class);
vo.setOnline(onlineUserIds.contains(m.getUserId())); vo.setOnline(onlineUserIds.contains(m.getUserId()));
return vo; return vo;
}).sorted((m1,m2)-> m2.getOnline().compareTo(m1.getOnline())).collect(Collectors.toList()); }).sorted((m1, m2) -> m2.getOnline().compareTo(m1.getOnline())).collect(Collectors.toList());
} }
} }

12
im-platform/src/main/java/com/bx/implatform/service/impl/PrivateMessageServiceImpl.java

@ -9,9 +9,8 @@ import com.bx.imclient.IMClient;
import com.bx.imcommon.contant.IMConstant; import com.bx.imcommon.contant.IMConstant;
import com.bx.imcommon.model.IMPrivateMessage; import com.bx.imcommon.model.IMPrivateMessage;
import com.bx.imcommon.model.IMUserInfo; import com.bx.imcommon.model.IMUserInfo;
import com.bx.implatform.dto.PrivateMessageDTO;
import com.bx.implatform.entity.Friend; import com.bx.implatform.entity.Friend;
import com.bx.implatform.util.DateTimeUtils;
import com.bx.implatform.vo.PrivateMessageVO;
import com.bx.implatform.entity.PrivateMessage; import com.bx.implatform.entity.PrivateMessage;
import com.bx.implatform.enums.MessageStatus; import com.bx.implatform.enums.MessageStatus;
import com.bx.implatform.enums.MessageType; import com.bx.implatform.enums.MessageType;
@ -23,7 +22,8 @@ import com.bx.implatform.service.IPrivateMessageService;
import com.bx.implatform.session.SessionContext; import com.bx.implatform.session.SessionContext;
import com.bx.implatform.session.UserSession; import com.bx.implatform.session.UserSession;
import com.bx.implatform.util.BeanUtils; import com.bx.implatform.util.BeanUtils;
import com.bx.implatform.dto.PrivateMessageDTO; import com.bx.implatform.util.DateTimeUtils;
import com.bx.implatform.vo.PrivateMessageVO;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -40,10 +40,8 @@ import java.util.stream.Collectors;
@AllArgsConstructor @AllArgsConstructor
public class PrivateMessageServiceImpl extends ServiceImpl<PrivateMessageMapper, PrivateMessage> implements IPrivateMessageService { public class PrivateMessageServiceImpl extends ServiceImpl<PrivateMessageMapper, PrivateMessage> implements IPrivateMessageService {
private IFriendService friendService; private final IFriendService friendService;
private final IMClient imClient;
private IMClient imClient;
@Override @Override
public Long sendMessage(PrivateMessageDTO dto) { public Long sendMessage(PrivateMessageDTO dto) {

100
im-platform/src/main/java/com/bx/implatform/service/impl/UserServiceImpl.java

@ -37,36 +37,34 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Slf4j @Slf4j
@Service @Service
@AllArgsConstructor @AllArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService { public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
RedisTemplate<String,Object> redisTemplate; private final RedisTemplate<String, Object> redisTemplate;
private PasswordEncoder passwordEncoder; private final PasswordEncoder passwordEncoder;
private IGroupMemberService groupMemberService; private final IGroupMemberService groupMemberService;
private IFriendService friendService; private final IFriendService friendService;
private JwtProperties jwtProperties; private final JwtProperties jwtProperties;
private IMClient imClient; private final IMClient imClient;
@Override @Override
public LoginVO login(LoginDTO dto) { public LoginVO login(LoginDTO dto) {
User user = this.findUserByUserName(dto.getUserName()); User user = this.findUserByUserName(dto.getUserName());
if(null == user){ if (null == user) {
throw new GlobalException(ResultCode.PROGRAM_ERROR,"用户不存在"); throw new GlobalException(ResultCode.PROGRAM_ERROR, "用户不存在");
} }
if(!passwordEncoder.matches(dto.getPassword(),user.getPassword())){ if (!passwordEncoder.matches(dto.getPassword(), user.getPassword())) {
throw new GlobalException(ResultCode.PASSWOR_ERROR); throw new GlobalException(ResultCode.PASSWOR_ERROR);
} }
// 生成token // 生成token
UserSession session = BeanUtils.copyProperties(user,UserSession.class); UserSession session = BeanUtils.copyProperties(user, UserSession.class);
session.setUserId(user.getId()); session.setUserId(user.getId());
session.setTerminal(dto.getTerminal()); session.setTerminal(dto.getTerminal());
String strJson = JSON.toJSONString(session); String strJson = JSON.toJSONString(session);
String accessToken = JwtUtil.sign(user.getId(),strJson,jwtProperties.getAccessTokenExpireIn(),jwtProperties.getAccessTokenSecret()); String accessToken = JwtUtil.sign(user.getId(), strJson, jwtProperties.getAccessTokenExpireIn(), jwtProperties.getAccessTokenSecret());
String refreshToken = JwtUtil.sign(user.getId(),strJson,jwtProperties.getRefreshTokenExpireIn(),jwtProperties.getRefreshTokenSecret()); String refreshToken = JwtUtil.sign(user.getId(), strJson, jwtProperties.getRefreshTokenExpireIn(), jwtProperties.getRefreshTokenSecret());
LoginVO vo = new LoginVO(); LoginVO vo = new LoginVO();
vo.setAccessToken(accessToken); vo.setAccessToken(accessToken);
vo.setAccessTokenExpiresIn(jwtProperties.getAccessTokenExpireIn()); vo.setAccessTokenExpiresIn(jwtProperties.getAccessTokenExpireIn());
@ -78,14 +76,14 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU
@Override @Override
public LoginVO refreshToken(String refreshToken) { public LoginVO refreshToken(String refreshToken) {
//验证 token //验证 token
if(!JwtUtil.checkSign(refreshToken, jwtProperties.getRefreshTokenSecret())){ if (!JwtUtil.checkSign(refreshToken, jwtProperties.getRefreshTokenSecret())) {
throw new GlobalException("refreshToken无效或已过期"); throw new GlobalException("refreshToken无效或已过期");
} }
String strJson = JwtUtil.getInfo(refreshToken); String strJson = JwtUtil.getInfo(refreshToken);
Long userId = JwtUtil.getUserId(refreshToken); Long userId = JwtUtil.getUserId(refreshToken);
String accessToken = JwtUtil.sign(userId,strJson,jwtProperties.getAccessTokenExpireIn(),jwtProperties.getAccessTokenSecret()); String accessToken = JwtUtil.sign(userId, strJson, jwtProperties.getAccessTokenExpireIn(), jwtProperties.getAccessTokenSecret());
String newRefreshToken = JwtUtil.sign(userId,strJson,jwtProperties.getRefreshTokenExpireIn(),jwtProperties.getRefreshTokenSecret()); String newRefreshToken = JwtUtil.sign(userId, strJson, jwtProperties.getRefreshTokenExpireIn(), jwtProperties.getRefreshTokenSecret());
LoginVO vo =new LoginVO(); LoginVO vo = new LoginVO();
vo.setAccessToken(accessToken); vo.setAccessToken(accessToken);
vo.setAccessTokenExpiresIn(jwtProperties.getAccessTokenExpireIn()); vo.setAccessTokenExpiresIn(jwtProperties.getAccessTokenExpireIn());
vo.setRefreshToken(newRefreshToken); vo.setRefreshToken(newRefreshToken);
@ -93,68 +91,63 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU
return vo; return vo;
} }
@Override @Override
public void register(RegisterDTO dto) { public void register(RegisterDTO dto) {
User user = this.findUserByUserName(dto.getUserName()); User user = this.findUserByUserName(dto.getUserName());
if(null != user){ if (null != user) {
throw new GlobalException(ResultCode.USERNAME_ALREADY_REGISTER); throw new GlobalException(ResultCode.USERNAME_ALREADY_REGISTER);
} }
user = BeanUtils.copyProperties(dto,User.class); user = BeanUtils.copyProperties(dto, User.class);
user.setPassword(passwordEncoder.encode(user.getPassword())); user.setPassword(passwordEncoder.encode(user.getPassword()));
this.save(user); this.save(user);
log.info("注册用户,用户id:{},用户名:{},昵称:{}",user.getId(),dto.getUserName(),dto.getNickName()); log.info("注册用户,用户id:{},用户名:{},昵称:{}", user.getId(), dto.getUserName(), dto.getNickName());
} }
@Override @Override
public void modifyPassword(ModifyPwdDTO dto) { public void modifyPassword(ModifyPwdDTO dto) {
UserSession session = SessionContext.getSession(); UserSession session = SessionContext.getSession();
User user = this.getById(session.getUserId()); User user = this.getById(session.getUserId());
if(!passwordEncoder.matches(dto.getOldPassword(),user.getPassword())){ if (!passwordEncoder.matches(dto.getOldPassword(), user.getPassword())) {
throw new GlobalException("旧密码不正确"); throw new GlobalException("旧密码不正确");
} }
user.setPassword(passwordEncoder.encode(dto.getNewPassword())); user.setPassword(passwordEncoder.encode(dto.getNewPassword()));
this.updateById(user); this.updateById(user);
log.info("用户修改密码,用户id:{},用户名:{},昵称:{}",user.getId(),user.getUserName(),user.getNickName()); log.info("用户修改密码,用户id:{},用户名:{},昵称:{}", user.getId(), user.getUserName(), user.getNickName());
} }
@Override @Override
public User findUserByUserName(String username) { public User findUserByUserName(String username) {
LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery(); LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.eq(User::getUserName,username); queryWrapper.eq(User::getUserName, username);
return this.getOne(queryWrapper); return this.getOne(queryWrapper);
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@Override @Override
public void update(UserVO vo) { public void update(UserVO vo) {
UserSession session = SessionContext.getSession(); UserSession session = SessionContext.getSession();
if(!session.getUserId().equals(vo.getId()) ){ if (!session.getUserId().equals(vo.getId())) {
throw new GlobalException(ResultCode.PROGRAM_ERROR,"不允许修改其他用户的信息!"); throw new GlobalException(ResultCode.PROGRAM_ERROR, "不允许修改其他用户的信息!");
} }
User user = this.getById(vo.getId()); User user = this.getById(vo.getId());
if(Objects.isNull(user)){ if (Objects.isNull(user)) {
throw new GlobalException(ResultCode.PROGRAM_ERROR,"用户不存在"); throw new GlobalException(ResultCode.PROGRAM_ERROR, "用户不存在");
} }
// 更新好友昵称和头像 // 更新好友昵称和头像
if(!user.getNickName().equals(vo.getNickName()) || !user.getHeadImageThumb().equals(vo.getHeadImageThumb())){ if (!user.getNickName().equals(vo.getNickName()) || !user.getHeadImageThumb().equals(vo.getHeadImageThumb())) {
QueryWrapper<Friend> queryWrapper = new QueryWrapper<>(); QueryWrapper<Friend> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(Friend::getFriendId,session.getUserId()); queryWrapper.lambda().eq(Friend::getFriendId, session.getUserId());
List<Friend> friends = friendService.list(queryWrapper); List<Friend> friends = friendService.list(queryWrapper);
for(Friend friend: friends){ for (Friend friend : friends) {
friend.setFriendNickName(vo.getNickName()); friend.setFriendNickName(vo.getNickName());
friend.setFriendHeadImage(vo.getHeadImageThumb()); friend.setFriendHeadImage(vo.getHeadImageThumb());
} }
friendService.updateBatchById(friends); friendService.updateBatchById(friends);
} }
// 更新群聊中的头像 // 更新群聊中的头像
if(!user.getHeadImageThumb().equals(vo.getHeadImageThumb())){ if (!user.getHeadImageThumb().equals(vo.getHeadImageThumb())) {
List<GroupMember> members = groupMemberService.findByUserId(session.getUserId()); List<GroupMember> members = groupMemberService.findByUserId(session.getUserId());
for(GroupMember member:members){ for (GroupMember member : members) {
member.setHeadImage(vo.getHeadImageThumb()); member.setHeadImage(vo.getHeadImageThumb());
} }
groupMemberService.updateBatchById(members); groupMemberService.updateBatchById(members);
@ -169,45 +162,38 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU
log.info("用户信息更新,用户:{}}", user); log.info("用户信息更新,用户:{}}", user);
} }
@Override @Override
public UserVO findUserById(Long id) { public UserVO findUserById(Long id) {
User user = this.getById(id); User user = this.getById(id);
UserVO vo = BeanUtils.copyProperties(user,UserVO.class); UserVO vo = BeanUtils.copyProperties(user, UserVO.class);
vo.setOnline(imClient.isOnline(id)); vo.setOnline(imClient.isOnline(id));
return vo; return vo;
} }
@Override @Override
public List<UserVO> findUserByName(String name) { public List<UserVO> findUserByName(String name) {
LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery(); LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.like(User::getUserName,name) queryWrapper.like(User::getUserName, name).or().like(User::getNickName, name).last("limit 20");
.or()
.like(User::getNickName,name)
.last("limit 20");
List<User> users = this.list(queryWrapper); List<User> users = this.list(queryWrapper);
List<Long> userIds = users.stream().map(User::getId).collect(Collectors.toList()); List<Long> userIds = users.stream().map(User::getId).collect(Collectors.toList());
List<Long> onlineUserIds = imClient.getOnlineUser(userIds); List<Long> onlineUserIds = imClient.getOnlineUser(userIds);
return users.stream().map(u-> { return users.stream().map(u -> {
UserVO vo = BeanUtils.copyProperties(u,UserVO.class); UserVO vo = BeanUtils.copyProperties(u, UserVO.class);
vo.setOnline(onlineUserIds.contains(u.getId())); vo.setOnline(onlineUserIds.contains(u.getId()));
return vo; return vo;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
} }
@Override @Override
public List<OnlineTerminalVO> getOnlineTerminals(String userIds) { public List<OnlineTerminalVO> getOnlineTerminals(String userIds) {
List<Long> userIdList = Arrays.stream(userIds.split(",")) List<Long> userIdList = Arrays.stream(userIds.split(",")).map(Long::parseLong).collect(Collectors.toList());
.map(Long::parseLong).collect(Collectors.toList());
// 查询在线的终端 // 查询在线的终端
Map<Long,List<IMTerminalType>> terminalMap = imClient.getOnlineTerminal(userIdList); Map<Long, List<IMTerminalType>> terminalMap = imClient.getOnlineTerminal(userIdList);
// 组装vo // 组装vo
List<OnlineTerminalVO> vos = new LinkedList<>(); List<OnlineTerminalVO> vos = new LinkedList<>();
terminalMap.forEach((userId,types)->{ terminalMap.forEach((userId, types) -> {
List<Integer> terminals = types.stream().map(IMTerminalType::code).collect(Collectors.toList()); List<Integer> terminals = types.stream().map(IMTerminalType::code).collect(Collectors.toList());
vos.add(new OnlineTerminalVO(userId,terminals)); vos.add(new OnlineTerminalVO(userId, terminals));
}); });
return vos; return vos;
} }

8
im-platform/src/main/java/com/bx/implatform/service/impl/WebrtcServiceImpl.java

@ -3,7 +3,6 @@ package com.bx.implatform.service.impl;
import com.bx.imclient.IMClient; import com.bx.imclient.IMClient;
import com.bx.imcommon.model.IMPrivateMessage; import com.bx.imcommon.model.IMPrivateMessage;
import com.bx.imcommon.model.IMUserInfo; import com.bx.imcommon.model.IMUserInfo;
import com.bx.implatform.vo.PrivateMessageVO;
import com.bx.implatform.config.ICEServer; import com.bx.implatform.config.ICEServer;
import com.bx.implatform.config.ICEServerConfig; import com.bx.implatform.config.ICEServerConfig;
import com.bx.implatform.contant.RedisKey; import com.bx.implatform.contant.RedisKey;
@ -13,6 +12,7 @@ import com.bx.implatform.service.IWebrtcService;
import com.bx.implatform.session.SessionContext; import com.bx.implatform.session.SessionContext;
import com.bx.implatform.session.UserSession; import com.bx.implatform.session.UserSession;
import com.bx.implatform.session.WebrtcSession; import com.bx.implatform.session.WebrtcSession;
import com.bx.implatform.vo.PrivateMessageVO;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
@ -28,9 +28,9 @@ import java.util.concurrent.TimeUnit;
@AllArgsConstructor @AllArgsConstructor
public class WebrtcServiceImpl implements IWebrtcService { public class WebrtcServiceImpl implements IWebrtcService {
private IMClient imClient; private final IMClient imClient;
private RedisTemplate<String, Object> redisTemplate; private final RedisTemplate<String, Object> redisTemplate;
private ICEServerConfig iceServerConfig; private final ICEServerConfig iceServerConfig;
@Override @Override
public void call(Long uid, String offer) { public void call(Long uid, String offer) {

21
im-platform/src/main/java/com/bx/implatform/service/thirdparty/FileService.java

@ -9,9 +9,9 @@ import com.bx.implatform.util.FileUtil;
import com.bx.implatform.util.ImageUtil; import com.bx.implatform.util.ImageUtil;
import com.bx.implatform.util.MinioUtil; import com.bx.implatform.util.MinioUtil;
import com.bx.implatform.vo.UploadImageVO; import com.bx.implatform.vo.UploadImageVO;
import lombok.RequiredArgsConstructor;
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.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -22,28 +22,25 @@ import java.io.IOException;
/** /**
* todo 通过校验文件MD5实现重复文件秒传 * todo 通过校验文件MD5实现重复文件秒传
* 文件上传服务 * 文件上传服务
* @Author Blue * @author Blue
* @Date 2022/10/28 * @date 2022/10/28
* *
*/ */
@Slf4j @Slf4j
@Service @Service
@RequiredArgsConstructor
public class FileService { public class FileService {
private final MinioUtil minioUtil;
@Autowired
private MinioUtil minioUtil;
@Value("${minio.public}") @Value("${minio.public}")
private String minIOServer; private String minIoServer;
@Value("${minio.bucketName}") @Value("${minio.bucketName}")
private String bucketName; private String bucketName;
@Value("${minio.imagePath}") @Value("${minio.imagePath}")
private String imagePath; private String imagePath;
@Value("${minio.filePath}") @Value("${minio.filePath}")
private String filePath; private String filePath;
@PostConstruct @PostConstruct
public void init(){ public void init(){
if(!minioUtil.bucketExists(bucketName)){ if(!minioUtil.bucketExists(bucketName)){
@ -108,7 +105,7 @@ public class FileService {
public String generUrl(FileType fileTypeEnum, String fileName){ public String generUrl(FileType fileTypeEnum, String fileName){
String url = minIOServer+"/"+bucketName; String url = minIoServer +"/"+bucketName;
switch (fileTypeEnum){ switch (fileTypeEnum){
case FILE: case FILE:
url += "/file/"; url += "/file/";
@ -119,6 +116,8 @@ public class FileService {
case VIDEO: case VIDEO:
url += "/video/"; url += "/video/";
break; break;
default:
break;
} }
url += fileName; url += fileName;
return url; return url;

2
im-platform/src/main/java/com/bx/implatform/session/WebrtcSession.java

@ -1,7 +1,5 @@
package com.bx.implatform.session; package com.bx.implatform.session;
import com.bx.imcommon.enums.IMTerminalType;
import io.swagger.models.auth.In;
import lombok.Data; import lombok.Data;
/* /*

133
im-platform/src/main/java/com/bx/implatform/util/BeanUtils.java

@ -1,13 +1,6 @@
package com.bx.implatform.util; package com.bx.implatform.util;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class BeanUtils { public class BeanUtils {
@ -17,63 +10,19 @@ public class BeanUtils {
} }
public static <T, U> List<U> copyProperties(List<T> sourceList, Class<U> clazz) {
if(sourceList == null || sourceList.size() <= 0) {
return new ArrayList<>();
}
List<U> result = new ArrayList<>();
for (T source : sourceList) {
result.add(copyProperties(source, clazz));
}
return result;
}
/** /**
* 如果source , 为空返回空对象 * 属性拷贝
* @param sourceList * @param orig 源对象
* @param clazz * @param destClass 目标
* @return * @return T
*/
public static <T, U> List<U> copyPropertiesList(List<T> sourceList, Class<U> clazz) {
if(sourceList == null || sourceList.size() <= 0) {
return new ArrayList<U>();
}
List<U> result = new ArrayList<>();
U target = null;
for (T source : sourceList) {
try {
target = clazz.newInstance();
copyProperties(source, target);
}catch(Exception e) {
handleReflectionException(e);
return new ArrayList<>();
}
result.add(target);
}
return result;
}
/**
* source空为null
* @param orig
* @param destClass
* @param <T>
* @return
*/ */
public static <T> T copyProperties(Object orig, Class<T> destClass) { public static <T> T copyProperties(Object orig, Class<T> destClass) {
try { try {
Object target = destClass.newInstance(); Object target = destClass.newInstance();
if(orig == null) { if(orig == null) {
return null; return null;
} }
copyProperties(orig, (Object)target); copyProperties(orig, target);
return (T) target; return (T) target;
}catch(Exception e) { }catch(Exception e) {
handleReflectionException(e); handleReflectionException(e);
@ -81,78 +30,6 @@ public class BeanUtils {
} }
} }
/**
* source 为null 返回 空对象
* @param orig
* @param destClass
* @param <T>
* @return
*/
public static <T> T copyProperty(Object orig, Class<T> destClass) {
try {
Object target = destClass.newInstance();
if(orig == null) {
return (T)target;
}
copyProperties(orig, (Object)target);
return (T) target;
}catch(Exception e) {
handleReflectionException(e);
Object o1 = new Object();
try {
o1 = destClass.newInstance();
}catch(Exception ex) {
handleReflectionException(e);
}
return (T)o1;
}
}
public static <T, U> List<U> copyProperties(List<T> sourceList, Class<U> clazz, String... ignoreProperties) {
if(sourceList == null || sourceList.size() <= 0) {
return new ArrayList<U>();
}
List<U> result = new ArrayList<>();
for (T source : sourceList) {
result.add(copyProperties(source, clazz, ignoreProperties));
}
return result;
}
public static <T> T copyProperties(Object orig, Class<T> destClass, String... ignoreProperties) {
if(orig == null) {
return null;
}
try {
Object target = destClass.newInstance();
org.springframework.beans.BeanUtils.copyProperties(orig, (Object)target, ignoreProperties);
return (T)target;
}catch(Exception e) {
return null;
}
}
public static String[] getNullPropertyNames(Object source) {
final BeanWrapper beanWrapper = new BeanWrapperImpl(source);
java.beans.PropertyDescriptor[] propDesc = beanWrapper.getPropertyDescriptors();
Set<String> emptynames = new HashSet<String>();
for(java.beans.PropertyDescriptor pd : propDesc) {
Object srcValue = beanWrapper.getPropertyValue(pd.getName());
if (srcValue == null) {emptynames.add(pd.getName());}
}
String[] result = new String[emptynames.size()];
return emptynames.toArray(result);
}
public static void copyProperties(Object orig, Object dest) { public static void copyProperties(Object orig, Object dest) {
try { try {

18
im-platform/src/main/java/com/bx/implatform/util/DateTimeUtils.java

@ -1,21 +1,10 @@
package com.bx.implatform.util; package com.bx.implatform.util;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.LocalDate; import java.util.Date;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
/** /**
* 日期处理工具类 * 日期处理工具类
@ -25,7 +14,6 @@ import java.util.*;
public class DateTimeUtils extends DateUtils { public class DateTimeUtils extends DateUtils {
public static final String FULL_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; public static final String FULL_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String PART_DATE_FORMAT = "yyyy-MM-dd";
public static final String PARTDATEFORMAT = "yyyyMMdd"; public static final String PARTDATEFORMAT = "yyyyMMdd";
@ -34,11 +22,11 @@ public class DateTimeUtils extends DateUtils {
* *
* @param date 日期 * @param date 日期
* @param xFormat 格式 * @param xFormat 格式
* @return * @return 日期
*/ */
public static String getFormatDate(Date date, String xFormat) { public static String getFormatDate(Date date, String xFormat) {
date = date == null ? new Date() : date; date = date == null ? new Date() : date;
xFormat = StringUtils.isNotEmpty(xFormat) == true ? xFormat : FULL_DATE_FORMAT; xFormat = StringUtils.isNotEmpty(xFormat) ? xFormat : FULL_DATE_FORMAT;
SimpleDateFormat sdf = new SimpleDateFormat(xFormat); SimpleDateFormat sdf = new SimpleDateFormat(xFormat);
return sdf.format(date); return sdf.format(date);
} }

3
im-platform/src/main/java/com/bx/implatform/util/FileUtil.java

@ -9,8 +9,7 @@ public class FileUtil {
* @return boolean * @return boolean
*/ */
public static String getFileExtension(String fileName) { public static String getFileExtension(String fileName) {
String extension = fileName.substring(fileName.lastIndexOf(".") + 1); return fileName.substring(fileName.lastIndexOf(".") + 1);
return extension;
} }
/** /**

58
im-platform/src/main/java/com/bx/implatform/util/MinioUtil.java

@ -2,9 +2,9 @@ package com.bx.implatform.util;
import io.minio.*; import io.minio.*;
import lombok.AllArgsConstructor;
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.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -14,11 +14,10 @@ import java.util.Date;
@Slf4j @Slf4j
@Component @Component
@AllArgsConstructor
public class MinioUtil { public class MinioUtil {
private final MinioClient minioClient;
@Autowired
private MinioClient minioClient;
/** /**
* 查看存储bucket是否存在 * 查看存储bucket是否存在
@ -35,25 +34,21 @@ public class MinioUtil {
/** /**
* 创建存储bucket * 创建存储bucket
* @return Boolean
*/ */
public Boolean makeBucket(String bucketName) { public void makeBucket(String bucketName) {
try { try {
minioClient.makeBucket(MakeBucketArgs.builder() minioClient.makeBucket(MakeBucketArgs.builder()
.bucket(bucketName) .bucket(bucketName)
.build()); .build());
} catch (Exception e) { } catch (Exception e) {
log.error("创建bucket失败,",e); log.error("创建bucket失败,",e);
return false;
} }
return true;
} }
/** /**
* 设置bucket权限为public * 设置bucket权限为public
* @return Boolean
*/ */
public Boolean setBucketPublic(String bucketName) { public void setBucketPublic(String bucketName) {
try { try {
// 设置公开 // 设置公开
String sb = "{\"Version\":\"2012-10-17\"," + String sb = "{\"Version\":\"2012-10-17\"," +
@ -70,34 +65,13 @@ public class MinioUtil {
.build()); .build());
} catch (Exception e) { } catch (Exception e) {
log.error("创建bucket失败,",e); log.error("创建bucket失败,",e);
return false;
} }
return true;
} }
/**
* 删除存储bucket
* @return Boolean
*/
public Boolean removeBucket(String bucketName) {
try {
minioClient.removeBucket(RemoveBucketArgs.builder()
.bucket(bucketName)
.build());
} catch (Exception e) {
log.error("删除bucket失败,",e);
return false;
}
return true;
}
/** /**
* 文件上传 * 文件上传
* @bucketName bucket名称 * @param bucketName bucket名称
* @path 路径 * @param path 路径
* @param file 文件 * @param file 文件
* @return Boolean * @return Boolean
*/ */
@ -129,8 +103,8 @@ public class MinioUtil {
* @param path 路径 * @param path 路径
* @param name 文件名 * @param name 文件名
* @param fileByte 文件内容 * @param fileByte 文件内容
* @param contentType * @param contentType contentType
* @return Boolean * @return objectName
*/ */
public String upload(String bucketName,String path,String name,byte[] fileByte,String contentType) { public String upload(String bucketName,String path,String name,byte[] fileByte,String contentType) {
@ -142,9 +116,8 @@ public class MinioUtil {
.stream(stream, fileByte.length, -1).contentType(contentType).build(); .stream(stream, fileByte.length, -1).contentType(contentType).build();
//文件名称相同会覆盖 //文件名称相同会覆盖
minioClient.putObject(objectArgs); minioClient.putObject(objectArgs);
} catch (Exception e) { } catch (Exception e) {
log.error("上传图片失败,",e); log.error("上传文件失败,",e);
return null; return null;
} }
return objectName; return objectName;
@ -154,16 +127,15 @@ public class MinioUtil {
/** /**
* 删除 * 删除
* @param bucketName bucket名称 * @param bucketName bucket名称
* @path path * @param path 路径
* @param fileName * @param fileName 文件名
* @return * @return true/false
* @throws Exception
*/ */
public boolean remove(String bucketName,String path,String fileName){ public boolean remove(String bucketName,String path,String fileName){
try { try {
minioClient.removeObject( RemoveObjectArgs.builder().bucket(bucketName).object(path+fileName).build()); minioClient.removeObject( RemoveObjectArgs.builder().bucket(bucketName).object(path+fileName).build());
}catch (Exception e){ }catch (Exception e){
log.error("删除图片失败,",e); log.error("删除文件失败,",e);
return false; return false;
} }
return true; return true;

4
im-platform/src/main/java/com/bx/implatform/util/XssUtil.java

@ -11,9 +11,7 @@ public class XssUtil {
public static boolean checkXss(String inputString) { public static boolean checkXss(String inputString) {
if (inputString!=null) { if (inputString!=null) {
Matcher matcher = PATTERN.matcher(inputString); Matcher matcher = PATTERN.matcher(inputString);
if (matcher.find()) { return matcher.find();
return true;
}
} }
return false; return false;
} }

1
im-platform/src/main/java/com/bx/implatform/vo/GroupVO.java

@ -6,7 +6,6 @@ import lombok.Data;
import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@Data @Data
@ApiModel("群信息VO") @ApiModel("群信息VO")

14
im-server/src/main/java/com/bx/imserver/config/RedisConfig.java

@ -1,27 +1,18 @@
package com.bx.imserver.config; package com.bx.imserver.config;
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer; import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer;
import javax.annotation.Resource;
@Configuration @Configuration
public class RedisConfig { public class RedisConfig {
@Bean @Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate(); RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory); redisTemplate.setConnectionFactory(redisConnectionFactory);
// 设置值(value)的序列化采用FastJsonRedisSerializer // 设置值(value)的序列化采用FastJsonRedisSerializer
redisTemplate.setValueSerializer(fastJsonRedisSerializer()); redisTemplate.setValueSerializer(fastJsonRedisSerializer());
@ -35,8 +26,7 @@ public class RedisConfig {
public FastJsonRedisSerializer fastJsonRedisSerializer(){ public FastJsonRedisSerializer fastJsonRedisSerializer(){
FastJsonRedisSerializer <Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); return new FastJsonRedisSerializer<>(Object.class);
return fastJsonRedisSerializer;
} }

23
im-server/src/main/java/com/bx/imserver/netty/IMChannelHandler.java

@ -27,12 +27,11 @@ public class IMChannelHandler extends SimpleChannelInboundHandler<IMSendInfo> {
/** /**
* 读取到消息后进行处理 * 读取到消息后进行处理
* *
* @param ctx * @param ctx channel上下文
* @param sendInfo * @param sendInfo 发送消息
* @throws Exception
*/ */
@Override @Override
protected void channelRead0(ChannelHandlerContext ctx, IMSendInfo sendInfo) throws Exception { protected void channelRead0(ChannelHandlerContext ctx, IMSendInfo sendInfo) {
// 创建处理器进行处理 // 创建处理器进行处理
AbstractMessageProcessor processor = ProcessorFactory.createProcessor(IMCmdType.fromCode(sendInfo.getCmd())); AbstractMessageProcessor processor = ProcessorFactory.createProcessor(IMCmdType.fromCode(sendInfo.getCmd()));
processor.process(ctx,processor.transForm(sendInfo.getData())); processor.process(ctx,processor.transForm(sendInfo.getData()));
@ -41,12 +40,11 @@ public class IMChannelHandler extends SimpleChannelInboundHandler<IMSendInfo> {
/** /**
* 出现异常的处理 打印报错日志 * 出现异常的处理 打印报错日志
* *
* @param ctx * @param ctx channel上下文
* @param cause * @param cause 异常信息
* @throws Exception
*/ */
@Override @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
log.error(cause.getMessage()); log.error(cause.getMessage());
//关闭上下文 //关闭上下文
//ctx.close(); //ctx.close();
@ -55,16 +53,15 @@ public class IMChannelHandler extends SimpleChannelInboundHandler<IMSendInfo> {
/** /**
* 监控浏览器上线 * 监控浏览器上线
* *
* @param ctx * @param ctx channel上下文
* @throws Exception
*/ */
@Override @Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception { public void handlerAdded(ChannelHandlerContext ctx) {
log.info(ctx.channel().id().asLongText() + "连接"); log.info(ctx.channel().id().asLongText() + "连接");
} }
@Override @Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { public void handlerRemoved(ChannelHandlerContext ctx) {
AttributeKey<Long> userIdAttr = AttributeKey.valueOf(ChannelAttrKey.USER_ID); AttributeKey<Long> userIdAttr = AttributeKey.valueOf(ChannelAttrKey.USER_ID);
Long userId = ctx.channel().attr(userIdAttr).get(); Long userId = ctx.channel().attr(userIdAttr).get();
AttributeKey<Integer> terminalAttr = AttributeKey.valueOf(ChannelAttrKey.TERMINAL_TYPE); AttributeKey<Integer> terminalAttr = AttributeKey.valueOf(ChannelAttrKey.TERMINAL_TYPE);
@ -75,7 +72,7 @@ public class IMChannelHandler extends SimpleChannelInboundHandler<IMSendInfo> {
// 移除channel // 移除channel
UserChannelCtxMap.removeChannelCtx(userId,terminal); UserChannelCtxMap.removeChannelCtx(userId,terminal);
// 用户下线 // 用户下线
RedisTemplate redisTemplate = SpringContextHolder.getBean("redisTemplate"); RedisTemplate<String,Object> redisTemplate = SpringContextHolder.getBean("redisTemplate");
String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID,userId.toString(), terminal.toString()); String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID,userId.toString(), terminal.toString());
redisTemplate.delete(key); redisTemplate.delete(key);
log.info("断开连接,userId:{},终端类型:{}",userId,terminal); log.info("断开连接,userId:{},终端类型:{}",userId,terminal);

1
im-server/src/main/java/com/bx/imserver/netty/IMServerGroup.java

@ -3,7 +3,6 @@ package com.bx.imserver.netty;
import com.bx.imcommon.contant.IMRedisKey; import com.bx.imcommon.contant.IMRedisKey;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner; import org.springframework.boot.CommandLineRunner;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;

1
im-server/src/main/java/com/bx/imserver/netty/UserChannelCtxMap.java

@ -2,7 +2,6 @@ package com.bx.imserver.netty;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;

5
im-server/src/main/java/com/bx/imserver/netty/processor/GroupMessageProcessor.java

@ -5,13 +5,12 @@ import com.bx.imcommon.enums.IMCmdType;
import com.bx.imcommon.enums.IMSendCode; import com.bx.imcommon.enums.IMSendCode;
import com.bx.imcommon.model.IMRecvInfo; import com.bx.imcommon.model.IMRecvInfo;
import com.bx.imcommon.model.IMSendInfo; import com.bx.imcommon.model.IMSendInfo;
import com.bx.imcommon.model.IMUserInfo;
import com.bx.imcommon.model.IMSendResult; import com.bx.imcommon.model.IMSendResult;
import com.bx.imcommon.model.IMUserInfo;
import com.bx.imserver.netty.UserChannelCtxMap; import com.bx.imserver.netty.UserChannelCtxMap;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -23,7 +22,7 @@ import java.util.List;
@AllArgsConstructor @AllArgsConstructor
public class GroupMessageProcessor extends AbstractMessageProcessor<IMRecvInfo> { public class GroupMessageProcessor extends AbstractMessageProcessor<IMRecvInfo> {
private RedisTemplate<String,Object> redisTemplate; private final RedisTemplate<String,Object> redisTemplate;
@Async @Async
@Override @Override

11
im-server/src/main/java/com/bx/imserver/netty/processor/HeartbeatProcessor.java

@ -7,12 +7,10 @@ import com.bx.imcommon.enums.IMCmdType;
import com.bx.imcommon.model.IMHeartbeatInfo; import com.bx.imcommon.model.IMHeartbeatInfo;
import com.bx.imcommon.model.IMSendInfo; import com.bx.imcommon.model.IMSendInfo;
import com.bx.imserver.constant.ChannelAttrKey; import com.bx.imserver.constant.ChannelAttrKey;
import com.bx.imserver.netty.ws.WebSocketServer;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.util.AttributeKey; import io.netty.util.AttributeKey;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -24,7 +22,7 @@ import java.util.concurrent.TimeUnit;
@AllArgsConstructor @AllArgsConstructor
public class HeartbeatProcessor extends AbstractMessageProcessor<IMHeartbeatInfo> { public class HeartbeatProcessor extends AbstractMessageProcessor<IMHeartbeatInfo> {
RedisTemplate<String,Object> redisTemplate; private final RedisTemplate<String, Object> redisTemplate;
@Override @Override
public void process(ChannelHandlerContext ctx, IMHeartbeatInfo beatInfo) { public void process(ChannelHandlerContext ctx, IMHeartbeatInfo beatInfo) {
@ -37,22 +35,21 @@ public class HeartbeatProcessor extends AbstractMessageProcessor<IMHeartbeatInfo
AttributeKey<Long> heartBeatAttr = AttributeKey.valueOf(ChannelAttrKey.HEARTBEAT_TIMES); AttributeKey<Long> heartBeatAttr = AttributeKey.valueOf(ChannelAttrKey.HEARTBEAT_TIMES);
Long heartbeatTimes = ctx.channel().attr(heartBeatAttr).get(); Long heartbeatTimes = ctx.channel().attr(heartBeatAttr).get();
ctx.channel().attr(heartBeatAttr).set(++heartbeatTimes); ctx.channel().attr(heartBeatAttr).set(++heartbeatTimes);
if(heartbeatTimes%10 == 0){ if (heartbeatTimes % 10 == 0) {
// 每心跳10次,用户在线状态续一次命 // 每心跳10次,用户在线状态续一次命
AttributeKey<Long> userIdAttr = AttributeKey.valueOf(ChannelAttrKey.USER_ID); AttributeKey<Long> userIdAttr = AttributeKey.valueOf(ChannelAttrKey.USER_ID);
Long userId = ctx.channel().attr(userIdAttr).get(); Long userId = ctx.channel().attr(userIdAttr).get();
AttributeKey<Integer> terminalAttr = AttributeKey.valueOf(ChannelAttrKey.TERMINAL_TYPE); AttributeKey<Integer> terminalAttr = AttributeKey.valueOf(ChannelAttrKey.TERMINAL_TYPE);
Integer terminal = ctx.channel().attr(terminalAttr).get(); Integer terminal = ctx.channel().attr(terminalAttr).get();
String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID,userId.toString(),terminal.toString()); String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID, userId.toString(), terminal.toString());
redisTemplate.expire(key, IMConstant.ONLINE_TIMEOUT_SECOND, TimeUnit.SECONDS); redisTemplate.expire(key, IMConstant.ONLINE_TIMEOUT_SECOND, TimeUnit.SECONDS);
} }
} }
@Override @Override
public IMHeartbeatInfo transForm(Object o) { public IMHeartbeatInfo transForm(Object o) {
HashMap map = (HashMap)o; HashMap map = (HashMap)o;
IMHeartbeatInfo heartbeatInfo = BeanUtil.fillBeanWithMap(map, new IMHeartbeatInfo(), false); IMHeartbeatInfo heartbeatInfo = BeanUtil.fillBeanWithMap(map, new IMHeartbeatInfo(), false);
return heartbeatInfo; return heartbeatInfo;
} }
} }

11
im-server/src/main/java/com/bx/imserver/netty/processor/LoginProcessor.java

@ -5,19 +5,17 @@ import com.alibaba.fastjson.JSON;
import com.bx.imcommon.contant.IMConstant; import com.bx.imcommon.contant.IMConstant;
import com.bx.imcommon.contant.IMRedisKey; import com.bx.imcommon.contant.IMRedisKey;
import com.bx.imcommon.enums.IMCmdType; import com.bx.imcommon.enums.IMCmdType;
import com.bx.imcommon.model.IMLoginInfo;
import com.bx.imcommon.model.IMSendInfo; import com.bx.imcommon.model.IMSendInfo;
import com.bx.imcommon.model.IMSessionInfo; import com.bx.imcommon.model.IMSessionInfo;
import com.bx.imcommon.model.IMLoginInfo;
import com.bx.imcommon.util.JwtUtil; import com.bx.imcommon.util.JwtUtil;
import com.bx.imserver.constant.ChannelAttrKey; import com.bx.imserver.constant.ChannelAttrKey;
import com.bx.imserver.netty.IMServerGroup; import com.bx.imserver.netty.IMServerGroup;
import com.bx.imserver.netty.UserChannelCtxMap; import com.bx.imserver.netty.UserChannelCtxMap;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.util.AttributeKey; import io.netty.util.AttributeKey;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -49,7 +47,7 @@ public class LoginProcessor extends AbstractMessageProcessor<IMLoginInfo> {
ChannelHandlerContext context = UserChannelCtxMap.getChannelCtx(userId,terminal); ChannelHandlerContext context = UserChannelCtxMap.getChannelCtx(userId,terminal);
if(context != null && !ctx.channel().id().equals(context.channel().id())){ if(context != null && !ctx.channel().id().equals(context.channel().id())){
// 不允许多地登录,强制下线 // 不允许多地登录,强制下线
IMSendInfo sendInfo = new IMSendInfo(); IMSendInfo<Object> sendInfo = new IMSendInfo<>();
sendInfo.setCmd(IMCmdType.FORCE_LOGUT.code()); sendInfo.setCmd(IMCmdType.FORCE_LOGUT.code());
sendInfo.setData("您已在其他地方登陆,将被强制下线"); sendInfo.setData("您已在其他地方登陆,将被强制下线");
context.channel().writeAndFlush(sendInfo); context.channel().writeAndFlush(sendInfo);
@ -70,7 +68,7 @@ public class LoginProcessor extends AbstractMessageProcessor<IMLoginInfo> {
String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID,userId.toString(), terminal.toString()); String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID,userId.toString(), terminal.toString());
redisTemplate.opsForValue().set(key, IMServerGroup.serverId, IMConstant.ONLINE_TIMEOUT_SECOND, TimeUnit.SECONDS); redisTemplate.opsForValue().set(key, IMServerGroup.serverId, IMConstant.ONLINE_TIMEOUT_SECOND, TimeUnit.SECONDS);
// 响应ws // 响应ws
IMSendInfo sendInfo = new IMSendInfo(); IMSendInfo<Object> sendInfo = new IMSendInfo<>();
sendInfo.setCmd(IMCmdType.LOGIN.code()); sendInfo.setCmd(IMCmdType.LOGIN.code());
ctx.channel().writeAndFlush(sendInfo); ctx.channel().writeAndFlush(sendInfo);
} }
@ -79,7 +77,6 @@ public class LoginProcessor extends AbstractMessageProcessor<IMLoginInfo> {
@Override @Override
public IMLoginInfo transForm(Object o) { public IMLoginInfo transForm(Object o) {
HashMap map = (HashMap)o; HashMap map = (HashMap)o;
IMLoginInfo loginInfo = BeanUtil.fillBeanWithMap(map, new IMLoginInfo(), false); return BeanUtil.fillBeanWithMap(map, new IMLoginInfo(), false);
return loginInfo;
} }
} }

9
im-server/src/main/java/com/bx/imserver/netty/processor/PrivateMessageProcessor.java

@ -5,13 +5,12 @@ import com.bx.imcommon.enums.IMCmdType;
import com.bx.imcommon.enums.IMSendCode; import com.bx.imcommon.enums.IMSendCode;
import com.bx.imcommon.model.IMRecvInfo; import com.bx.imcommon.model.IMRecvInfo;
import com.bx.imcommon.model.IMSendInfo; import com.bx.imcommon.model.IMSendInfo;
import com.bx.imcommon.model.IMUserInfo;
import com.bx.imcommon.model.IMSendResult; import com.bx.imcommon.model.IMSendResult;
import com.bx.imcommon.model.IMUserInfo;
import com.bx.imserver.netty.UserChannelCtxMap; import com.bx.imserver.netty.UserChannelCtxMap;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -20,7 +19,7 @@ import org.springframework.stereotype.Component;
@AllArgsConstructor @AllArgsConstructor
public class PrivateMessageProcessor extends AbstractMessageProcessor<IMRecvInfo> { public class PrivateMessageProcessor extends AbstractMessageProcessor<IMRecvInfo> {
private RedisTemplate<String,Object> redisTemplate; private final RedisTemplate<String,Object> redisTemplate;
@Override @Override
public void process(IMRecvInfo recvInfo) { public void process(IMRecvInfo recvInfo) {
@ -31,7 +30,7 @@ public class PrivateMessageProcessor extends AbstractMessageProcessor<IMRecvInfo
ChannelHandlerContext channelCtx = UserChannelCtxMap.getChannelCtx(receiver.getId(),receiver.getTerminal()); ChannelHandlerContext channelCtx = UserChannelCtxMap.getChannelCtx(receiver.getId(),receiver.getTerminal());
if(channelCtx != null ){ if(channelCtx != null ){
// 推送消息到用户 // 推送消息到用户
IMSendInfo sendInfo = new IMSendInfo(); IMSendInfo<Object> sendInfo = new IMSendInfo<>();
sendInfo.setCmd(IMCmdType.PRIVATE_MESSAGE.code()); sendInfo.setCmd(IMCmdType.PRIVATE_MESSAGE.code());
sendInfo.setData(recvInfo.getData()); sendInfo.setData(recvInfo.getData());
channelCtx.channel().writeAndFlush(sendInfo); channelCtx.channel().writeAndFlush(sendInfo);
@ -52,7 +51,7 @@ public class PrivateMessageProcessor extends AbstractMessageProcessor<IMRecvInfo
private void sendResult(IMRecvInfo recvInfo,IMSendCode sendCode){ private void sendResult(IMRecvInfo recvInfo,IMSendCode sendCode){
if(recvInfo.getSendResult()) { if(recvInfo.getSendResult()) {
IMSendResult result = new IMSendResult(); IMSendResult<Object> result = new IMSendResult<>();
result.setSender(recvInfo.getSender()); result.setSender(recvInfo.getSender());
result.setReceiver(recvInfo.getReceivers().get(0)); result.setReceiver(recvInfo.getReceivers().get(0));
result.setCode(sendCode.code()); result.setCode(sendCode.code());

8
im-server/src/main/java/com/bx/imserver/netty/processor/ProcessorFactory.java

@ -9,16 +9,16 @@ public class ProcessorFactory {
AbstractMessageProcessor processor = null; AbstractMessageProcessor processor = null;
switch (cmd){ switch (cmd){
case LOGIN: case LOGIN:
processor = (AbstractMessageProcessor) SpringContextHolder.getApplicationContext().getBean(LoginProcessor.class); processor = SpringContextHolder.getApplicationContext().getBean(LoginProcessor.class);
break; break;
case HEART_BEAT: case HEART_BEAT:
processor = (AbstractMessageProcessor) SpringContextHolder.getApplicationContext().getBean(HeartbeatProcessor.class); processor = SpringContextHolder.getApplicationContext().getBean(HeartbeatProcessor.class);
break; break;
case PRIVATE_MESSAGE: case PRIVATE_MESSAGE:
processor = (AbstractMessageProcessor)SpringContextHolder.getApplicationContext().getBean(PrivateMessageProcessor.class); processor = SpringContextHolder.getApplicationContext().getBean(PrivateMessageProcessor.class);
break; break;
case GROUP_MESSAGE: case GROUP_MESSAGE:
processor = (AbstractMessageProcessor)SpringContextHolder.getApplicationContext().getBean(GroupMessageProcessor.class); processor = SpringContextHolder.getApplicationContext().getBean(GroupMessageProcessor.class);
break; break;
default: default:
break; break;

7
im-server/src/main/java/com/bx/imserver/netty/ws/WebSocketServer.java

@ -37,7 +37,6 @@ public class WebSocketServer implements IMServer {
private volatile boolean ready = false; private volatile boolean ready = false;
private ServerBootstrap bootstrap;
private EventLoopGroup bossGroup; private EventLoopGroup bossGroup;
private EventLoopGroup workGroup; private EventLoopGroup workGroup;
@ -49,7 +48,7 @@ public class WebSocketServer implements IMServer {
@Override @Override
public void start() { public void start() {
bootstrap = new ServerBootstrap(); ServerBootstrap bootstrap = new ServerBootstrap();
bossGroup = new NioEventLoopGroup(); bossGroup = new NioEventLoopGroup();
workGroup = new NioEventLoopGroup(); workGroup = new NioEventLoopGroup();
// 设置为主从线程模型 // 设置为主从线程模型
@ -60,7 +59,7 @@ public class WebSocketServer implements IMServer {
.childHandler(new ChannelInitializer<Channel>() { .childHandler(new ChannelInitializer<Channel>() {
// 添加处理的Handler,通常包括消息编解码、业务处理,也可以是日志、权限、过滤等 // 添加处理的Handler,通常包括消息编解码、业务处理,也可以是日志、权限、过滤等
@Override @Override
protected void initChannel(Channel ch) throws Exception { protected void initChannel(Channel ch) {
// 获取职责链 // 获取职责链
ChannelPipeline pipeline = ch.pipeline(); ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new IdleStateHandler(120, 0, 0, TimeUnit.SECONDS)); pipeline.addLast(new IdleStateHandler(120, 0, 0, TimeUnit.SECONDS));
@ -82,7 +81,7 @@ public class WebSocketServer implements IMServer {
try { try {
// 绑定端口,启动select线程,轮询监听channel事件,监听到事件之后就会交给从线程池处理 // 绑定端口,启动select线程,轮询监听channel事件,监听到事件之后就会交给从线程池处理
Channel channel = bootstrap.bind(port).sync().channel(); bootstrap.bind(port).sync().channel();
// 就绪标志 // 就绪标志
this.ready = true; this.ready = true;
log.info("websocket server 初始化完成,端口:{}",port); log.info("websocket server 初始化完成,端口:{}",port);

1
im-server/src/main/java/com/bx/imserver/netty/ws/endecode/MessageProtocolEncoder.java

@ -14,7 +14,6 @@ public class MessageProtocolEncoder extends MessageToMessageEncoder<IMSendInfo>
protected void encode(ChannelHandlerContext channelHandlerContext, IMSendInfo sendInfo, List<Object> list) throws Exception { protected void encode(ChannelHandlerContext channelHandlerContext, IMSendInfo sendInfo, List<Object> list) throws Exception {
ObjectMapper objectMapper = new ObjectMapper(); ObjectMapper objectMapper = new ObjectMapper();
String text = objectMapper.writeValueAsString(sendInfo); String text = objectMapper.writeValueAsString(sendInfo);
TextWebSocketFrame frame = new TextWebSocketFrame(text); TextWebSocketFrame frame = new TextWebSocketFrame(text);
list.add(frame); list.add(frame);
} }

4
im-server/src/main/java/com/bx/imserver/task/AbstractPullMessageTask.java

@ -6,9 +6,9 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner; import org.springframework.boot.CommandLineRunner;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import java.util.concurrent.*; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Slf4j @Slf4j
public abstract class AbstractPullMessageTask implements CommandLineRunner { public abstract class AbstractPullMessageTask implements CommandLineRunner {

7
im-server/src/main/java/com/bx/imserver/task/PullGroupMessageTask.java

@ -7,18 +7,19 @@ import com.bx.imcommon.model.IMRecvInfo;
import com.bx.imserver.netty.IMServerGroup; import com.bx.imserver.netty.IMServerGroup;
import com.bx.imserver.netty.processor.AbstractMessageProcessor; import com.bx.imserver.netty.processor.AbstractMessageProcessor;
import com.bx.imserver.netty.processor.ProcessorFactory; import com.bx.imserver.netty.processor.ProcessorFactory;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@Slf4j @Slf4j
@Component @Component
@AllArgsConstructor
public class PullGroupMessageTask extends AbstractPullMessageTask { public class PullGroupMessageTask extends AbstractPullMessageTask {
@Autowired private final RedisTemplate<String,Object> redisTemplate;
private RedisTemplate<String,Object> redisTemplate;
@Override @Override
public void pullMessage() { public void pullMessage() {

9
im-server/src/main/java/com/bx/imserver/task/PullPrivateMessageTask.java

@ -1,6 +1,5 @@
package com.bx.imserver.task; package com.bx.imserver.task;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.bx.imcommon.contant.IMRedisKey; import com.bx.imcommon.contant.IMRedisKey;
import com.bx.imcommon.enums.IMCmdType; import com.bx.imcommon.enums.IMCmdType;
@ -8,19 +7,19 @@ import com.bx.imcommon.model.IMRecvInfo;
import com.bx.imserver.netty.IMServerGroup; import com.bx.imserver.netty.IMServerGroup;
import com.bx.imserver.netty.processor.AbstractMessageProcessor; import com.bx.imserver.netty.processor.AbstractMessageProcessor;
import com.bx.imserver.netty.processor.ProcessorFactory; import com.bx.imserver.netty.processor.ProcessorFactory;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@Slf4j @Slf4j
@Component @Component
@AllArgsConstructor
public class PullPrivateMessageTask extends AbstractPullMessageTask { public class PullPrivateMessageTask extends AbstractPullMessageTask {
private final RedisTemplate<String,Object> redisTemplate;
@Autowired
private RedisTemplate<String,Object> redisTemplate;
@Override @Override
public void pullMessage() { public void pullMessage() {

Loading…
Cancel
Save