diff --git a/commons/src/main/java/com/ivmiku/tutorial/response/AtNotifier.java b/commons/src/main/java/com/ivmiku/tutorial/response/AtNotifier.java new file mode 100644 index 0000000..360627e --- /dev/null +++ b/commons/src/main/java/com/ivmiku/tutorial/response/AtNotifier.java @@ -0,0 +1,14 @@ +package com.ivmiku.tutorial.response; + +import lombok.Data; + +/** + * 提醒用户实体 + * @author Aurora + */ +@Data +public class AtNotifier { + private String fromId; + private String toId; + private String postId; +} diff --git a/community-8073/pom.xml b/community-8073/pom.xml index 6f9a9f6..74ce4eb 100644 --- a/community-8073/pom.xml +++ b/community-8073/pom.xml @@ -190,6 +190,14 @@ commons 1.0-SNAPSHOT + + org.springframework.boot + spring-boot-starter-amqp + + + org.springframework.boot + spring-boot-starter-websocket + diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/controller/CommentController.java b/community-8073/src/main/java/com/ivmiku/tutorial/controller/CommentController.java index af8dc9a..992e47c 100644 --- a/community-8073/src/main/java/com/ivmiku/tutorial/controller/CommentController.java +++ b/community-8073/src/main/java/com/ivmiku/tutorial/controller/CommentController.java @@ -2,17 +2,21 @@ package com.ivmiku.tutorial.controller; import cn.dev33.satoken.annotation.SaCheckLogin; import cn.dev33.satoken.stp.StpUtil; +import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.metadata.IPage; import com.github.pagehelper.PageInfo; import com.ivmiku.tutorial.entity.Comment; import com.ivmiku.tutorial.entity.Pages; +import com.ivmiku.tutorial.response.AtNotifier; import com.ivmiku.tutorial.response.Result; import com.ivmiku.tutorial.service.CommentService; import com.ivmiku.tutorial.service.FileService; +import com.ivmiku.tutorial.util.MyRedisUtil; import io.swagger.v3.oas.annotations.Operation; import org.apiguardian.api.API; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -36,6 +40,13 @@ public class CommentController { @Resource private FileService fileService; + @Resource + private RabbitTemplate rabbitTemplate; + + @Resource + private MyRedisUtil redisUtil; + + /** * 创建评论接口。 */ @@ -66,6 +77,14 @@ public class CommentController { commentService.createComment(comment); logger.info("评论创建成功,评论ID:{}", comment.getCommentId()); + if (!mentionedUserId.isEmpty()) { + AtNotifier notifier = new AtNotifier(); + notifier.setFromId(comment.getUserOpenid()); + notifier.setToId(mentionedUserId); + notifier.setPostId(String.valueOf(comment.getCommentId())); + rabbitTemplate.convertAndSend("exchange2", "", JSON.toJSONString(notifier)); + redisUtil.listAdd("at:" + notifier.getToId(), JSON.toJSONString(notifier)); + } return Result.ok(comment); } @@ -106,6 +125,14 @@ public class CommentController { commentService.createComment(reply); logger.info("评论回复成功,评论ID:{}", reply.getCommentId()); + if (!mentionedUserId.isEmpty()) { + AtNotifier notifier = new AtNotifier(); + notifier.setFromId(reply.getUserOpenid()); + notifier.setToId(mentionedUserId); + notifier.setPostId(String.valueOf(reply.getCommentId())); + rabbitTemplate.convertAndSend("exchange2", "", JSON.toJSONString(notifier)); + redisUtil.listAdd("at:" + notifier.getToId(), JSON.toJSONString(notifier)); + } return Result.ok(reply); } @@ -115,7 +142,6 @@ public class CommentController { comment.setUserOpenid(StpUtil.getLoginIdAsString()); comment.setContent(content); comment.setMentionedUserId(mentionedUserId); - if ("post".equals(type)) { comment.setPostId(postId); } else if ("tutorial".equals(type)) { diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/controller/WebSocketServer.java b/community-8073/src/main/java/com/ivmiku/tutorial/controller/WebSocketServer.java new file mode 100644 index 0000000..2e52100 --- /dev/null +++ b/community-8073/src/main/java/com/ivmiku/tutorial/controller/WebSocketServer.java @@ -0,0 +1,73 @@ +package com.ivmiku.tutorial.controller; + +import cn.dev33.satoken.stp.StpUtil; +import com.alibaba.fastjson.JSON; +import com.ivmiku.tutorial.entity.UserDTO; +import com.ivmiku.tutorial.response.Result; +import com.ivmiku.tutorial.service.impl.SearchService; +import jakarta.websocket.*; +import jakarta.websocket.server.PathParam; +import jakarta.websocket.server.ServerEndpoint; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Controller; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@Controller +@ServerEndpoint(value = "/search/{satoken}") +public class WebSocketServer { + public static Map sessionMap = new ConcurrentHashMap<>(); + private static ApplicationContext applicationContext; + private SearchService searchService; + + @OnOpen + public void onOpen(Session session, EndpointConfig endpointConfig, @PathParam("satoken") String satoken) throws IOException { + String userId = (String) StpUtil.getLoginIdByToken(satoken); + if (userId == null) { + session.getBasicRemote().sendText("Invalid Token"); + session.close(); + } + sessionMap.put(userId, session); + this.searchService = WebSocketServer.applicationContext.getBean(SearchService.class); + } + + @OnClose + public void onClose(CloseReason closeReason, Session session){ + sessionMap.remove(session.getId()); + } + + @OnError + public void onError(Throwable throwable) throws IOException { + throwable.printStackTrace(); + } + + @OnMessage + public void onMessage(String message, Session session) throws IOException { + char first = message.charAt(0); + String userId = null; + for (Map.Entry entry : sessionMap.entrySet()) { + if (entry.getValue().equals(session)) { + userId = entry.getKey(); + } + } + switch (first) { + case '@' -> { + String sub = message.substring(1); + List result = searchService.getUserList(sub, userId); + session.getBasicRemote().sendText(JSON.toJSONString(Result.ok(result))); + } + case '#' -> { + String sub = message.substring(1); + List list = searchService.getTag(message); + session.getBasicRemote().sendText(JSON.toJSONString(Result.ok(list))); + } + //预留给社区搜索 + default -> { + + } + } + } +} diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/entity/Subscribe.java b/community-8073/src/main/java/com/ivmiku/tutorial/entity/Subscribe.java new file mode 100644 index 0000000..054070f --- /dev/null +++ b/community-8073/src/main/java/com/ivmiku/tutorial/entity/Subscribe.java @@ -0,0 +1,13 @@ +package com.ivmiku.tutorial.entity; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * @author Aurora + */ +@TableName("subscribe") +@Data +public class Subscribe { + private Long id; + private Long subId; +} diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/entity/User.java b/community-8073/src/main/java/com/ivmiku/tutorial/entity/User.java index 7dd39f4..ab3b4e3 100644 --- a/community-8073/src/main/java/com/ivmiku/tutorial/entity/User.java +++ b/community-8073/src/main/java/com/ivmiku/tutorial/entity/User.java @@ -4,11 +4,15 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; +@TableName("user") @Data -@TableName("User") public class User { @TableId private String openid; private String nickname; private String avatarUrl; + private boolean isAdmin; + private String phoneNum; + private String birthday; + private String gender; } diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/entity/UserDTO.java b/community-8073/src/main/java/com/ivmiku/tutorial/entity/UserDTO.java new file mode 100644 index 0000000..fb0b383 --- /dev/null +++ b/community-8073/src/main/java/com/ivmiku/tutorial/entity/UserDTO.java @@ -0,0 +1,12 @@ +package com.ivmiku.tutorial.entity; + +import lombok.Data; + +@Data +public class UserDTO { + private String nickname; + private String avatarUrl; + private String phoneNum; + private String birthday; + private String gender; +} diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/mapper/SubscribeMapper.java b/community-8073/src/main/java/com/ivmiku/tutorial/mapper/SubscribeMapper.java new file mode 100644 index 0000000..53d67c9 --- /dev/null +++ b/community-8073/src/main/java/com/ivmiku/tutorial/mapper/SubscribeMapper.java @@ -0,0 +1,8 @@ +package com.ivmiku.tutorial.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ivmiku.tutorial.entity.Subscribe; + +public interface SubscribeMapper extends BaseMapper { + +} diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/mapper/UserMapper.java b/community-8073/src/main/java/com/ivmiku/tutorial/mapper/UserMapper.java new file mode 100644 index 0000000..f220728 --- /dev/null +++ b/community-8073/src/main/java/com/ivmiku/tutorial/mapper/UserMapper.java @@ -0,0 +1,7 @@ +package com.ivmiku.tutorial.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ivmiku.tutorial.entity.User; + +public interface UserMapper extends BaseMapper { +} diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/CommentServiceImpl.java b/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/CommentServiceImpl.java index 55d409a..ad8aac6 100644 --- a/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/CommentServiceImpl.java +++ b/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/CommentServiceImpl.java @@ -1,6 +1,7 @@ package com.ivmiku.tutorial.service.impl; import cn.dev33.satoken.stp.StpUtil; +import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -8,10 +9,13 @@ import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.ivmiku.tutorial.entity.Comment; import com.ivmiku.tutorial.mapper.CommentMapper; +import com.ivmiku.tutorial.response.AtNotifier; import com.ivmiku.tutorial.service.CommentService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import jakarta.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -30,6 +34,9 @@ public class CommentServiceImpl extends ServiceImpl impl @Autowired protected CommentMapper commentMapper; + @Resource + private RabbitTemplate rabbitTemplate; + /** * 保存评论。 * 将评论数据保存到数据库。 @@ -186,6 +193,13 @@ public class CommentServiceImpl extends ServiceImpl impl reply.setMentionedUserId(mentionedUserId); } createComment(reply); + if (mentionedUserId != null) { + AtNotifier notifier = new AtNotifier(); + notifier.setFromId(reply.getUserOpenid()); + notifier.setToId(mentionedUserId); + notifier.setPostId(String.valueOf(reply.getCommentId())); + rabbitTemplate.convertAndSend("exchange2", "", JSON.toJSONString(notifier)); + } logger.info("评论回复成功,评论ID:{}", reply.getCommentId()); } diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/SearchService.java b/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/SearchService.java new file mode 100644 index 0000000..0b28037 --- /dev/null +++ b/community-8073/src/main/java/com/ivmiku/tutorial/service/impl/SearchService.java @@ -0,0 +1,58 @@ +package com.ivmiku.tutorial.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.ivmiku.tutorial.entity.Subscribe; +import com.ivmiku.tutorial.entity.Tag; +import com.ivmiku.tutorial.entity.User; +import com.ivmiku.tutorial.entity.UserDTO; +import com.ivmiku.tutorial.mapper.PostTagMapper; +import com.ivmiku.tutorial.mapper.SubscribeMapper; +import com.ivmiku.tutorial.mapper.TagMapper; +import com.ivmiku.tutorial.mapper.UserMapper; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; + +@Service +public class SearchService { + @Resource + private UserMapper userMapper; + + @Resource + private TagMapper tagMapper; + + @Resource + private SubscribeMapper subscribeMapper; + + public List getUserList(String text, String userId) { + int len = text.length(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("user1_id", userId); + List list = subscribeMapper.selectList(queryWrapper); + List result = new ArrayList<>(); + for (Subscribe subscribe : list) { + String user2Id = String.valueOf(subscribe.getSubId()); + User user = userMapper.selectById(user2Id); + if (user.getNickname().substring(0, len).equals(text)) { + UserDTO userDTO = new UserDTO(); + userDTO.setNickname(user.getNickname()); + userDTO.setAvatarUrl(user.getAvatarUrl()); + result.add(userDTO); + } + } + return result; + } + + public List getTag(String text) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.likeRight("name", text); + List list = tagMapper.selectList(queryWrapper); + List result = new ArrayList<>(); + for (Tag tag : list) { + result.add(tag.getName()); + } + return result; + } +} diff --git a/community-8073/src/main/java/com/ivmiku/tutorial/util/MyRedisUtil.java b/community-8073/src/main/java/com/ivmiku/tutorial/util/MyRedisUtil.java new file mode 100644 index 0000000..a39b99a --- /dev/null +++ b/community-8073/src/main/java/com/ivmiku/tutorial/util/MyRedisUtil.java @@ -0,0 +1,94 @@ +package com.ivmiku.tutorial.util; + +import com.alibaba.fastjson2.JSON; +import com.ivmiku.tutorial.response.AtNotifier; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * @author Aurora + */ +@Component +public class MyRedisUtil { + @Autowired + private RedisTemplate redisTemplate; + + public void listAdd(String key, Object value) { + redisTemplate.opsForList().leftPush(key, value); + } + + public List listGet(String key, int s, int e) { + List list = redisTemplate.opsForList().range(key, s, e); + List result = new ArrayList<>(); + if (list != null) { + for (Object json : list) { + result.add(JSON.parseObject(JSON.toJSONString(json), AtNotifier.class)); + } + } + return result; + } + + public void listClear(String key) { + redisTemplate.opsForList().trim(key, 1, 0); + } + + public Long getListSize(String key) { + return redisTemplate.opsForList().size(key); + } + + public Set getKey() { + return redisTemplate.keys("history:*"); + } + + public Object rightPop(String key) { + return redisTemplate.opsForList().rightPop(key); + } + + + + + + public void setExpireTime(String key) { + if (redisTemplate.opsForValue().getOperations().getExpire(key) > 0) { + redisTemplate.expire(key, 3, TimeUnit.DAYS); + } + } + + public void refreshExpire(String key) { + redisTemplate.persist(key); + redisTemplate.expire(key, 3, TimeUnit.DAYS); + } + + public boolean ifExist(String key) { + return Boolean.TRUE.equals(redisTemplate.hasKey(key)); + } + + public List getStringList(String key, int s, int e) { + List list = redisTemplate.opsForList().range(key, s, e); + List result = new ArrayList<>(); + assert list != null; + for (Object object : list) { + result.add((String) object); + } + return result; + } + + public void insertKey(String openid, String sessionKey) { + redisTemplate.opsForValue().set("sessionkey:" + openid, sessionKey); + } + + public String getKey(String userId) { + return (String) redisTemplate.opsForValue().get("sessionkey:" + userId); + } + + public void deleteFromList(AtNotifier message) { + String id = message.getToId(); + redisTemplate.opsForList().remove("unread:" + id, 0, message); + } +} diff --git a/community-8073/src/main/resources/application-dep.properties b/community-8073/src/main/resources/application-dep.properties index ba52002..43a6c58 100644 --- a/community-8073/src/main/resources/application-dep.properties +++ b/community-8073/src/main/resources/application-dep.properties @@ -13,15 +13,12 @@ server.port=8073 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.username=root -spring.datasource.password=123456 +spring.datasource.password=Shuodedaoli114514 spring.datasource.url=jdbc:mysql://mysql:3306/tutorial?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true spring.cloud.nacos.discovery.server-addr=nacos:8848 spring.cloud.nacos.discovery.enabled=true -management.zipkin.tracing.endpoint=http://127.0.0.1:9411/api/v2/spans -management.tracing.sampling.probability=1.0 - dubbo.application.qos-enable=false mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl diff --git a/navigate-8432/src/main/resources/application-dev.properties b/navigate-8432/src/main/resources/application-dev.properties index cc170df..676fc04 100644 --- a/navigate-8432/src/main/resources/application-dev.properties +++ b/navigate-8432/src/main/resources/application-dev.properties @@ -10,5 +10,5 @@ dubbo.application.qos-enable=false spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.username=root -spring.datasource.password=12345abcde -spring.datasource.url=jdbc:mysql://127.0.0.1:3306/tutorial?useUnicode=true&characterEncoding=utf8&useSSL=false&ServerTimezone=Asia/Shanghai +spring.datasource.password=Shuodedaoli114514 +spring.datasource.url=jdbc:mysql://154.40.44.199:4514/tutorial?useUnicode=true&characterEncoding=utf8&useSSL=false&ServerTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/config/RabbitMqConfig.java b/user-8072/src/main/java/com/ivmiku/tutorial/config/RabbitMqConfig.java index d9ee381..90f436a 100644 --- a/user-8072/src/main/java/com/ivmiku/tutorial/config/RabbitMqConfig.java +++ b/user-8072/src/main/java/com/ivmiku/tutorial/config/RabbitMqConfig.java @@ -14,14 +14,29 @@ public class RabbitMqConfig { return new Queue("queue1",true); } + @Bean + public Queue queue2() { + return new Queue("queue2",true); + } + @Bean public FanoutExchange exchange1() { return new FanoutExchange("exchange1",true, false); } + @Bean + public FanoutExchange exchange2() { + return new FanoutExchange("exchange2",true, false); + } + @Bean public Binding binding1() { return BindingBuilder.bind(queue1()).to(exchange1()); } + + @Bean + public Binding binding2() { + return BindingBuilder.bind(queue2()).to(exchange2()); + } } diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/controller/WebSocketServer.java b/user-8072/src/main/java/com/ivmiku/tutorial/controller/WebSocketServer.java index 3f27ac6..2bc217f 100644 --- a/user-8072/src/main/java/com/ivmiku/tutorial/controller/WebSocketServer.java +++ b/user-8072/src/main/java/com/ivmiku/tutorial/controller/WebSocketServer.java @@ -2,7 +2,9 @@ package com.ivmiku.tutorial.controller; import cn.dev33.satoken.stp.StpUtil; import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; import com.ivmiku.tutorial.entity.Message; +import com.ivmiku.tutorial.response.AtNotifier; import com.ivmiku.tutorial.service.MessageService; import com.ivmiku.tutorial.service.RelationService; import com.ivmiku.tutorial.utils.DateUtil; @@ -84,7 +86,15 @@ public class WebSocketServer implements ApplicationContextAware { sessionMap.put(userId, session); List unreadList = messageService.getUnreadMsg(userId); for(Message msg : unreadList) { - session.getBasicRemote().sendText(JSON.toJSONString(msg)); + JSONObject object = JSONObject.from(msg); + object.put("type", 1); + session.getBasicRemote().sendText(object.toJSONString()); + } + List atList = messageService.getAtList(userId); + for (AtNotifier notifier : atList) { + JSONObject object = JSONObject.from(notifier); + object.put("type", 2); + session.getBasicRemote().sendText(object.toJSONString()); } } @@ -132,8 +142,25 @@ public class WebSocketServer implements ApplicationContextAware { public void sendMsg(String message) throws IOException { Message msg = JSON.parseObject(message, Message.class); if (sessionMap.containsKey(msg.getToId())) { - sessionMap.get(msg.getToId()).getBasicRemote().sendText(JSON.toJSONString(msg)); + JSONObject jsonObject = JSONObject.from(msg); + jsonObject.put("type", 1); + sessionMap.get(msg.getToId()).getBasicRemote().sendText(jsonObject.toJSONString()); messageService.deleteMessage(msg); } } + + @RabbitHandler + @RabbitListener(bindings = @QueueBinding( + value = @Queue(), + exchange = @Exchange(value = "exchange2",type = ExchangeTypes.FANOUT) + )) + public void sendAt(String message) throws IOException { + AtNotifier notifier = JSON.parseObject(message, AtNotifier.class); + if (sessionMap.containsKey(notifier.getToId())) { + JSONObject jsonObject = JSONObject.from(notifier); + jsonObject.put("type", 2); + sessionMap.get(notifier.getToId()).getBasicRemote().sendText(jsonObject.toJSONString()); + messageService.deleteNotifier(notifier); + } + } } diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/service/MessageService.java b/user-8072/src/main/java/com/ivmiku/tutorial/service/MessageService.java index 779c1d5..1e318e2 100644 --- a/user-8072/src/main/java/com/ivmiku/tutorial/service/MessageService.java +++ b/user-8072/src/main/java/com/ivmiku/tutorial/service/MessageService.java @@ -6,6 +6,7 @@ import com.ivmiku.tutorial.entity.ChatId; import com.ivmiku.tutorial.entity.Message; import com.ivmiku.tutorial.mapper.ChatIdMapper; import com.ivmiku.tutorial.mapper.MessageMapper; +import com.ivmiku.tutorial.response.AtNotifier; import com.ivmiku.tutorial.utils.RedisUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; @@ -245,4 +246,12 @@ public class MessageService { public void deleteMessage(Message message) { redisUtil.deleteFromList(message); } + + public void deleteNotifier(AtNotifier notifier) { + redisUtil.deleteFromList(notifier); + } + + public List getAtList(String userId) { + return redisUtil.listGetN("at:" + userId, 0, -1); + } } diff --git a/user-8072/src/main/java/com/ivmiku/tutorial/utils/RedisUtil.java b/user-8072/src/main/java/com/ivmiku/tutorial/utils/RedisUtil.java index fb0c172..0160371 100644 --- a/user-8072/src/main/java/com/ivmiku/tutorial/utils/RedisUtil.java +++ b/user-8072/src/main/java/com/ivmiku/tutorial/utils/RedisUtil.java @@ -2,6 +2,7 @@ package com.ivmiku.tutorial.utils; import com.alibaba.fastjson2.JSON; import com.ivmiku.tutorial.entity.Message; +import com.ivmiku.tutorial.response.AtNotifier; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; @@ -127,4 +128,24 @@ public class RedisUtil { String id = message.getToId(); redisTemplate.opsForList().remove("unread:" + id, 0, message); } + + public void listAddN(String key, Object value) { + redisTemplate.opsForList().leftPush(key, value); + } + + public List listGetN(String key, int s, int e) { + List list = redisTemplate.opsForList().range(key, s, e); + List result = new ArrayList<>(); + if (list != null) { + for (Object json : list) { + result.add(JSON.parseObject(JSON.toJSONString(json), AtNotifier.class)); + } + } + return result; + } + + public void deleteFromList(AtNotifier message) { + String id = message.getToId(); + redisTemplate.opsForList().remove("unread:" + id, 0, message); + } }