diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/MessageMark.java b/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/MessageMark.java
index 25a551c..a6cd1e0 100644
--- a/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/MessageMark.java
+++ b/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/MessageMark.java
@@ -7,7 +7,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.io.Serializable;
-import java.time.LocalDateTime;
+import java.util.Date;
/**
*
@@ -63,13 +63,13 @@ public class MessageMark implements Serializable {
* 创建时间
*/
@TableField("create_time")
- private LocalDateTime createTime;
+ private Date createTime;
/**
* 修改时间
*/
@TableField("update_time")
- private LocalDateTime updateTime;
+ private Date updateTime;
}
diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/msg/MessageExtra.java b/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/msg/MessageExtra.java
index 94dfcfc..32c04c1 100644
--- a/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/msg/MessageExtra.java
+++ b/mallchat-common/src/main/java/com/abin/mallchat/common/chat/domain/entity/msg/MessageExtra.java
@@ -7,6 +7,7 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
+import java.util.List;
import java.util.Map;
/**
@@ -25,4 +26,6 @@ public class MessageExtra implements Serializable {
private Map urlTitleMap;
//消息撤回详情
private MsgRecall recall;
+ //艾特的uid
+ private List atUidList;
}
diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/config/RedisConfig.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/config/RedisConfig.java
index 85518d5..ae52ae6 100644
--- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/config/RedisConfig.java
+++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/config/RedisConfig.java
@@ -15,7 +15,8 @@ import java.util.Objects;
@Configuration
public class RedisConfig {
- @Bean
+
+ @Bean("myRedisTemplate")
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
// 创建模板
RedisTemplate redisTemplate = new RedisTemplate<>();
@@ -30,10 +31,11 @@ public class RedisConfig {
// value和 hashValue采用 JSON序列化
redisTemplate.setValueSerializer(jsonRedisSerializer);
redisTemplate.setHashValueSerializer(jsonRedisSerializer);
+ redisTemplate.afterPropertiesSet();
return redisTemplate;
}
- public class MyRedisSerializerCustomized extends GenericJackson2JsonRedisSerializer {
+ private static class MyRedisSerializerCustomized extends GenericJackson2JsonRedisSerializer {
@Override
public byte[] serialize(Object source) throws SerializationException {
if (Objects.nonNull(source)) {
diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/constant/RedisKey.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/constant/RedisKey.java
index c0c5efc..faa6bd2 100644
--- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/constant/RedisKey.java
+++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/constant/RedisKey.java
@@ -26,6 +26,16 @@ public class RedisKey {
*/
public static final String USER_TOKEN_STRING = "userToken:uid_%d";
+ /**
+ * 用户的信息更新时间
+ */
+ public static final String USER_MODIFY_STRING = "userModify:uid_%d";
+
+ /**
+ * 用户的信息汇总
+ */
+ public static final String USER_SUMMARY_STRING = "userSummary:uid_%d";
+
public static String getKey(String key, Object... objects) {
return BASE_KEY + String.format(key, objects);
}
diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/event/MessageMarkEvent.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/event/MessageMarkEvent.java
index 5cd7906..6107641 100644
--- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/event/MessageMarkEvent.java
+++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/event/MessageMarkEvent.java
@@ -6,10 +6,12 @@ import org.springframework.context.ApplicationEvent;
@Getter
public class MessageMarkEvent extends ApplicationEvent {
- private ChatMessageMarkDTO dto;
+
+ private final ChatMessageMarkDTO dto;
public MessageMarkEvent(Object source, ChatMessageMarkDTO dto) {
super(source);
this.dto = dto;
}
+
}
diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/event/MessageRecallEvent.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/event/MessageRecallEvent.java
index c32f397..24d27fd 100644
--- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/event/MessageRecallEvent.java
+++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/event/MessageRecallEvent.java
@@ -6,10 +6,12 @@ import org.springframework.context.ApplicationEvent;
@Getter
public class MessageRecallEvent extends ApplicationEvent {
- private ChatMsgRecallDTO recallDTO;
+
+ private final ChatMsgRecallDTO recallDTO;
public MessageRecallEvent(Object source, ChatMsgRecallDTO recallDTO) {
super(source);
this.recallDTO = recallDTO;
}
+
}
diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/GlobalExceptionHandler.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/GlobalExceptionHandler.java
index 66e0b70..fad1667 100644
--- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/GlobalExceptionHandler.java
+++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/exception/GlobalExceptionHandler.java
@@ -3,6 +3,7 @@ package com.abin.mallchat.common.common.exception;
import com.abin.mallchat.common.common.domain.vo.response.ApiResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@@ -62,4 +63,14 @@ public class GlobalExceptionHandler {
log.info("business exception!The reason is:{}", e.getMessage(), e);
return ApiResult.fail(e.getErrorCode(), e.getMessage());
}
-}
\ No newline at end of file
+
+ /**
+ * http请求方式不支持
+ */
+ @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
+ public ApiResult handleException(HttpRequestMethodNotSupportedException e) {
+ log.error(e.getMessage(), e);
+ return ApiResult.fail(-1, String.format("不支持'%s'请求", e.getMethod()));
+ }
+
+}
diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/cache/AbstractRedisStringCache.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/cache/AbstractRedisStringCache.java
new file mode 100644
index 0000000..16b0f16
--- /dev/null
+++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/cache/AbstractRedisStringCache.java
@@ -0,0 +1,66 @@
+package com.abin.mallchat.common.common.service.cache;
+
+import cn.hutool.core.collection.CollectionUtil;
+import com.abin.mallchat.common.common.utils.RedisUtils;
+import org.springframework.data.util.Pair;
+
+import java.lang.reflect.ParameterizedType;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Description: redis string类型的批量缓存框架
+ * Author: abin
+ * Date: 2023-06-10
+ */
+public abstract class AbstractRedisStringCache implements BatchCache {
+
+ private Class outClass;
+
+ protected AbstractRedisStringCache() {
+ ParameterizedType genericSuperclass = (ParameterizedType) this.getClass().getGenericSuperclass();
+ this.outClass = (Class) genericSuperclass.getActualTypeArguments()[1];
+ }
+
+ protected abstract String getKey(IN req);
+
+ protected abstract Long getExpireSeconds();
+
+ protected abstract Map load(List req);
+
+ @Override
+ public OUT get(IN req) {
+ return getBatch(Collections.singletonList(req)).get(req);
+ }
+
+ @Override
+ public Map getBatch(List req) {
+ List keys = req.stream().map(this::getKey).collect(Collectors.toList());
+ List valueList = RedisUtils.mget(keys, outClass);
+ List loadReqs = new ArrayList<>();
+ for (int i = 0; i < valueList.size(); i++) {
+ if (Objects.isNull(valueList.get(i))) {
+ loadReqs.add(req.get(i));
+ }
+ }
+ Map load = new HashMap<>();
+ //不足的重新加载进redis
+ if (CollectionUtil.isNotEmpty(loadReqs)) {
+ load = load(loadReqs);
+ Map loadMap = load.entrySet().stream()
+ .map(a -> Pair.of(getKey(a.getKey()), a.getValue()))
+ .collect(Collectors.toMap(Pair::getFirst, Pair::getSecond));
+ RedisUtils.mset(loadMap, getExpireSeconds());
+ }
+
+ //组装最后的结果
+ Map resultMap = new HashMap<>();
+ for (int i = 0; i < req.size(); i++) {
+ IN in = req.get(i);
+ OUT out = Optional.ofNullable(valueList.get(i))
+ .orElse(load.get(in));
+ resultMap.put(in, out);
+ }
+ return resultMap;
+ }
+}
diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/cache/BatchCache.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/cache/BatchCache.java
new file mode 100644
index 0000000..1d97529
--- /dev/null
+++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/service/cache/BatchCache.java
@@ -0,0 +1,16 @@
+package com.abin.mallchat.common.common.service.cache;
+
+import java.util.List;
+import java.util.Map;
+
+public interface BatchCache {
+ /**
+ * 获取单个
+ */
+ OUT get(IN req);
+
+ /**
+ * 获取批量
+ */
+ Map getBatch(List req);
+}
diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/CursorUtils.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/CursorUtils.java
index 4eb2ff5..4d2a391 100644
--- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/CursorUtils.java
+++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/CursorUtils.java
@@ -44,7 +44,7 @@ public class CursorUtils {
.map(String::valueOf)
.orElse(null);
Boolean isLast = result.size() != cursorPageBaseReq.getPageSize();
- return new CursorPageBaseResp(cursor, isLast, result);
+ return new CursorPageBaseResp<>(cursor, isLast, result);
}
public CursorPageBaseResp getCursorPageByMysql(IService mapper, CursorPageBaseReq request, Consumer> initWrapper, SFunction cursorColumn) {
@@ -60,7 +60,7 @@ public class CursorUtils {
.map(String::valueOf)
.orElse(null);
Boolean isLast = page.getRecords().size() != request.getPageSize();
- return new CursorPageBaseResp(cursor, isLast, page.getRecords());
+ return new CursorPageBaseResp<>(cursor, isLast, page.getRecords());
}
}
diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/RedisUtils.java b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/RedisUtils.java
index e694ec1..415c676 100644
--- a/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/RedisUtils.java
+++ b/mallchat-common/src/main/java/com/abin/mallchat/common/common/utils/RedisUtils.java
@@ -8,23 +8,17 @@ import org.springframework.data.redis.core.*;
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
-import org.springframework.stereotype.Component;
-import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
-
@Slf4j
-@Component
public class RedisUtils {
- public RedisTemplate redisTemplate;
private static StringRedisTemplate stringRedisTemplate;
- @PostConstruct
- public void init() {
+ static {
RedisUtils.stringRedisTemplate = SpringUtil.getBean(StringRedisTemplate.class);
}
@@ -49,7 +43,7 @@ public class RedisUtils {
* @param key 键
* @param time 时间(秒)
*/
- public static boolean expire(String key, long time) {
+ public static Boolean expire(String key, long time) {
try {
if (time > 0) {
stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
@@ -68,10 +62,10 @@ public class RedisUtils {
* @param time 时间(秒)
* @param timeUnit 单位
*/
- public boolean expire(String key, long time, TimeUnit timeUnit) {
+ public static Boolean expire(String key, long time, TimeUnit timeUnit) {
try {
if (time > 0) {
- redisTemplate.expire(key, time, timeUnit);
+ stringRedisTemplate.expire(key, time, timeUnit);
}
} catch (Exception e) {
log.error(e.getMessage(), e);
@@ -86,7 +80,7 @@ public class RedisUtils {
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
- public static long getExpire(String key) {
+ public static Long getExpire(String key) {
return stringRedisTemplate.getExpire(key, TimeUnit.SECONDS);
}
@@ -96,7 +90,7 @@ public class RedisUtils {
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
- public static long getExpire(String key, TimeUnit timeUnit) {
+ public static Long getExpire(String key, TimeUnit timeUnit) {
return stringRedisTemplate.getExpire(key, timeUnit);
}
@@ -106,9 +100,9 @@ public class RedisUtils {
* @param pattern key
* @return /
*/
- public List scan(String pattern) {
+ public static List scan(String pattern) {
ScanOptions options = ScanOptions.scanOptions().match(pattern).build();
- RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
+ RedisConnectionFactory factory = stringRedisTemplate.getConnectionFactory();
RedisConnection rc = Objects.requireNonNull(factory).getConnection();
Cursor cursor = rc.scan(options);
List result = new ArrayList<>();
@@ -131,9 +125,9 @@ public class RedisUtils {
* @param size 每页数目
* @return /
*/
- public List findKeysForPage(String patternKey, int page, int size) {
+ public static List findKeysForPage(String patternKey, int page, int size) {
ScanOptions options = ScanOptions.scanOptions().match(patternKey).build();
- RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
+ RedisConnectionFactory factory = stringRedisTemplate.getConnectionFactory();
RedisConnection rc = Objects.requireNonNull(factory).getConnection();
Cursor cursor = rc.scan(options);
List result = new ArrayList<>(size);
@@ -167,9 +161,9 @@ public class RedisUtils {
* @param key 键
* @return true 存在 false不存在
*/
- public boolean hasKey(String key) {
+ public static Boolean hasKey(String key) {
try {
- return redisTemplate.hasKey(key);
+ return stringRedisTemplate.hasKey(key);
} catch (Exception e) {
log.error(e.getMessage(), e);
return false;
@@ -185,21 +179,23 @@ public class RedisUtils {
public static void del(String... keys) {
if (keys != null && keys.length > 0) {
if (keys.length == 1) {
- boolean result = stringRedisTemplate.delete(keys[0]);
- log.debug("--------------------------------------------");
- log.debug(new StringBuilder("删除缓存:").append(keys[0]).append(",结果:").append(result).toString());
+ Boolean result = stringRedisTemplate.delete(keys[0]);
log.debug("--------------------------------------------");
+ log.debug("删除缓存:" + keys[0] + ",结果:" + result);
} else {
Set keySet = new HashSet<>();
for (String key : keys) {
- keySet.addAll(stringRedisTemplate.keys(key));
+ Set stringSet = stringRedisTemplate.keys(key);
+ if (Objects.nonNull(stringSet) && !stringSet.isEmpty()) {
+ keySet.addAll(stringSet);
+ }
}
- long count = stringRedisTemplate.delete(keySet);
+ Long count = stringRedisTemplate.delete(keySet);
log.debug("--------------------------------------------");
- log.debug("成功删除缓存:" + keySet.toString());
+ log.debug("成功删除缓存:" + keySet);
log.debug("缓存删除数量:" + count + "个");
- log.debug("--------------------------------------------");
}
+ log.debug("--------------------------------------------");
}
}
@@ -222,7 +218,7 @@ public class RedisUtils {
* @param value 值
* @return true成功 false失败
*/
- public static boolean set(String key, Object value) {
+ public static Boolean set(String key, Object value) {
try {
stringRedisTemplate.opsForValue().set(key, objToStr(value));
return true;
@@ -243,7 +239,10 @@ public class RedisUtils {
public static List mget(Collection keys, Class tClass) {
List list = stringRedisTemplate.opsForValue().multiGet(keys);
- return (List) list.stream().map(o -> toBeanOrNull(o, tClass)).collect(Collectors.toList());
+ if (Objects.isNull(list)) {
+ return new ArrayList<>();
+ }
+ return list.stream().map(o -> toBeanOrNull(o, tClass)).collect(Collectors.toList());
}
static T toBeanOrNull(String json, Class tClass) {
@@ -271,10 +270,10 @@ public class RedisUtils {
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
- public boolean set(String key, Object value, long time) {
+ public static Boolean set(String key, Object value, long time) {
try {
if (time > 0) {
- redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
+ stringRedisTemplate.opsForValue().set(key, objToStr(value), time, TimeUnit.SECONDS);
} else {
set(key, value);
}
@@ -294,7 +293,7 @@ public class RedisUtils {
* @param timeUnit 类型
* @return true成功 false 失败
*/
- public static boolean set(String key, Object value, long time, TimeUnit timeUnit) {
+ public static Boolean set(String key, Object value, long time, TimeUnit timeUnit) {
try {
if (time > 0) {
stringRedisTemplate.opsForValue().set(key, objToStr(value), time, timeUnit);
@@ -317,8 +316,8 @@ public class RedisUtils {
* @param item 项 不能为null
* @return 值
*/
- public Object hget(String key, String item) {
- return redisTemplate.opsForHash().get(key, item);
+ public static Object hget(String key, String item) {
+ return stringRedisTemplate.opsForHash().get(key, item);
}
/**
@@ -327,8 +326,8 @@ public class RedisUtils {
* @param key 键
* @return 对应的多个键值
*/
- public Map