nnkwrik преди 6 години
родител
ревизия
f06a934f42

+ 30 - 0
im-service/src/main/java/io/github/nnkwrik/imservice/controller/ChatController.java

@@ -4,12 +4,15 @@ import io.github.nnkwrik.common.dto.JWTUser;
 import io.github.nnkwrik.common.dto.Response;
 import io.github.nnkwrik.common.token.injection.JWT;
 import io.github.nnkwrik.imservice.model.po.LastChat;
+import io.github.nnkwrik.imservice.model.vo.ChatForm;
 import io.github.nnkwrik.imservice.model.vo.ChatIndex;
 import io.github.nnkwrik.imservice.redis.RedisClient;
+import io.github.nnkwrik.imservice.service.FormService;
 import io.github.nnkwrik.imservice.service.IndexService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
@@ -29,6 +32,9 @@ public class ChatController {
     @Autowired
     private IndexService indexService;
 
+    @Autowired
+    private FormService formService;
+
     //用于打开小程序时
     @GetMapping("/chat/unreadCount")
     public Response<Integer> getUnreadCount(@JWT JWTUser user) {
@@ -57,4 +63,28 @@ public class ChatController {
         return Response.ok(voList);
     }
 
+    //打开聊天框时
+    @GetMapping("/chat/form/{chatId}")
+    public Response<ChatForm> getChatForm(@PathVariable("chatId") int chatId,
+                                          @JWT(required = true) JWTUser user,
+                                          @RequestParam(value = "page", defaultValue = "1") int page,
+                                          @RequestParam(value = "size", defaultValue = "10") int size,
+                                          @RequestParam(value = "offset", defaultValue = "0") int offset) {
+        //offset,在聊天框的时候收到的消息个数
+        flushUnread(chatId, user);
+        ChatForm vo = formService.showForm(chatId, user.getOpenId(), page, size, offset);
+        log.info("用户openId={}获取与用户openId={}的聊天记录,展示 {} 条记录", user.getOpenId(), vo.getOtherSide().getOpenId(), vo.getHistoryList().size());
+
+        return Response.ok(vo);
+    }
+
+    //把所有未读设为已读, 在退出聊天框时使用
+    @GetMapping("/chat/flushUnread/{chatId}")
+    public Response flushUnread(@PathVariable("chatId") int chatId,
+                                @JWT(required = true) JWTUser user) {
+        redisClient.hdel(user.getOpenId(), chatId + "");
+        log.info("用户openId={}chatId={}的所有未读消息设为已读", user.getOpenId(), chatId);
+        return Response.ok();
+    }
+
 }

+ 4 - 19
im-service/src/main/java/io/github/nnkwrik/imservice/dao/ChatMapper.java

@@ -12,28 +12,13 @@ import org.apache.ibatis.annotations.SelectKey;
  */
 @Mapper
 public interface ChatMapper {
-//    @Select("select id, u1, u2, unread_count\n" +
-//            "from chat_user\n" +
-//            "where ((u1 = #{open_id} and u1_to_u2 = false) or (u2 = #{open_id} and u1_to_u2 = true))\n" +
-//            "  and unread_count > 0")
-//    Chat getUserUnreadChat(@Param("open_id") String openId);
-
-//    @Select("select unread_count from chat_user where u1=#{u1} and u2=#{u2}")
-//    Integer getUnreadCountByChat(@Param("u1") String u1Id, @Param("u2") String u2Id);
-
-
-//    Integer getUnreadCount(@Param("u1") String u1Id, @Param("u2") String u2Id);
-
-    @Select("select id\n" +
-            "from chat\n" +
-            "where u1 = #{u1}\n" +
-            "  and u2 = #{u2}\n" +
-            "  and goods_id = #{goods_id}")
-    Integer getChatId(@Param("u1") String u1, @Param("u2") String u2, @Param("goods_id") int goodsId);
-
 
     @Select("insert into chat (u1, u2, goods_id)\n" +
             "values (#{u1}, #{u2}, #{goodsId})")
     @SelectKey(resultType = Integer.class, before = false, keyProperty = "id", statement = "SELECT LAST_INSERT_ID()")
     void addChat(Chat chat);
+
+    @Select("select u1,u2,goods_id from chat where id = #{id}")
+    Chat getChatById(@Param("id") int id);
+
 }

+ 19 - 8
im-service/src/main/java/io/github/nnkwrik/imservice/dao/HistoryMapper.java

@@ -14,6 +14,10 @@ import java.util.List;
  */
 @Mapper
 public interface HistoryMapper {
+    /**
+     * 添加一条聊天记录
+     * @param history
+     */
     @Select("insert into history (chat_id, u1_to_u2, message_type, message_body, send_time)\n" +
             "values (#{chatId}, #{u1ToU2}, #{messageType}, #{messageBody}, #{sendTime});")
     void addHistory(History history);
@@ -21,6 +25,7 @@ public interface HistoryMapper {
 
     /**
      * 获取自己和所有人的最后一条"已读的"聊天记录,按时间倒序
+     *
      * @param unreadChatIds 未读的chatId
      * @return
      */
@@ -37,7 +42,7 @@ public interface HistoryMapper {
             "                       </foreach>\n" +
             "                       and ((u1 = 1 and show_to_u1 = true) or (u2 = 1 and show_to_u2 = true)))\n" +
             "                   group by chat_id) as foo on foo.chat_id = history.chat_id and foo.max_time = history.send_time\n" +
-            "        inner join chat where history.chat_id = chat.id\n"+
+            "        inner join chat where history.chat_id = chat.id\n" +
             "order by send_time desc" +
             "</script>")
     List<HistoryExample> getLastReadChat(@Param("unreadChatIds") List<Integer> unreadChatIds);
@@ -45,6 +50,7 @@ public interface HistoryMapper {
 
     /**
      * 获取自己和所有人的最后一条聊天记录,按时间倒序
+     *
      * @return
      */
     @Select("select history.chat_id, history.message_type, history.message_body, history.send_time, chat.u1, chat.u2, chat.goods_id\n" +
@@ -54,14 +60,19 @@ public interface HistoryMapper {
             "                   where chat_id in\n" +
             "                         (select id from chat where ((u1 = 1 and show_to_u1 = true) or (u2 = 1 and show_to_u2 = true)))\n" +
             "                   group by chat_id) as foo on foo.chat_id = history.chat_id and foo.max_time = history.send_time\n" +
-            "        inner join chat where history.chat_id = chat.id\n"+
+            "        inner join chat where history.chat_id = chat.id\n" +
             "order by send_time desc")
     List<HistoryExample> getLastChat();
 
-//    @Select("select message_type,hint,message_body,create_time\n" +
-//            "from chat_history\n" +
-//            "where chat_user_id = 1\n" +
-//            "ORDER BY create_time DESC\n" +
-//            "LIMIT 1")
-//    History getMostRecentByChatId(@Param("chat_user_id")Integer chatUserId);
+    /**
+     * 根据chatId获取聊天记录
+     * @param chat_id
+     * @return
+     */
+    @Select("select u1_to_u2, message_type, message_body, send_time\n" +
+            "from history\n" +
+            "where chat_id = #{chat_id}")
+    List<History> getChatHistory(@Param("chat_id") int chat_id);
+
+
 }

+ 20 - 0
im-service/src/main/java/io/github/nnkwrik/imservice/model/vo/ChatForm.java

@@ -0,0 +1,20 @@
+package io.github.nnkwrik.imservice.model.vo;
+
+import io.github.nnkwrik.common.dto.SimpleGoods;
+import io.github.nnkwrik.common.dto.SimpleUser;
+import io.github.nnkwrik.imservice.model.po.History;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author nnkwrik
+ * @date 18/12/07 22:33
+ */
+@Data
+public class ChatForm {
+    private SimpleUser otherSide;
+    private SimpleGoods goods;
+    private Boolean isU1;
+    private List<History> historyList;
+}

+ 1 - 1
im-service/src/main/java/io/github/nnkwrik/imservice/model/vo/ChatIndex.java

@@ -11,8 +11,8 @@ import lombok.Data;
  */
 @Data
 public class ChatIndex {
+    private Integer unreadCount;
     private SimpleUser otherSide;
     private SimpleGoods goods;
-    private Integer unreadCount;
     private History lastChat;
 }

+ 4 - 0
im-service/src/main/java/io/github/nnkwrik/imservice/redis/RedisClient.java

@@ -27,4 +27,8 @@ public class RedisClient {
     public <T> List<T> hvals(String key) {
         return redisTemplate.opsForHash().values(key);
     }
+
+    public void hdel(String key,String... fields){
+        redisTemplate.opsForHash().delete(key,fields);
+    }
 }

+ 12 - 0
im-service/src/main/java/io/github/nnkwrik/imservice/service/FormService.java

@@ -0,0 +1,12 @@
+package io.github.nnkwrik.imservice.service;
+
+import io.github.nnkwrik.imservice.model.vo.ChatForm;
+
+/**
+ * @author nnkwrik
+ * @date 18/12/07 22:36
+ */
+public interface FormService {
+    
+    ChatForm showForm(int chatId, String userId, int page, int size, int offset);
+}

+ 103 - 0
im-service/src/main/java/io/github/nnkwrik/imservice/service/impl/FormServiceImpl.java

@@ -0,0 +1,103 @@
+package io.github.nnkwrik.imservice.service.impl;
+
+import com.github.pagehelper.PageHelper;
+import io.github.nnkwrik.common.dto.Response;
+import io.github.nnkwrik.common.dto.SimpleGoods;
+import io.github.nnkwrik.common.dto.SimpleUser;
+import io.github.nnkwrik.imservice.client.GoodsClient;
+import io.github.nnkwrik.imservice.client.UserClient;
+import io.github.nnkwrik.imservice.dao.ChatMapper;
+import io.github.nnkwrik.imservice.dao.HistoryMapper;
+import io.github.nnkwrik.imservice.model.po.Chat;
+import io.github.nnkwrik.imservice.model.po.History;
+import io.github.nnkwrik.imservice.model.vo.ChatForm;
+import io.github.nnkwrik.imservice.redis.RedisClient;
+import io.github.nnkwrik.imservice.service.FormService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author nnkwrik
+ * @date 18/12/07 22:39
+ */
+@Service
+@Slf4j
+public class FormServiceImpl implements FormService {
+
+    @Autowired
+    private RedisClient redisClient;
+
+    @Autowired
+    private HistoryMapper historyMapper;
+
+    @Autowired
+    private ChatMapper chatMapper;
+
+    @Autowired
+    private UserClient userClient;
+
+    @Autowired
+    private GoodsClient goodsClient;
+
+    @Override
+    public ChatForm showForm(int chatId, String userId, int page, int size, int offset) {
+        ChatForm vo = new ChatForm();
+
+        Chat chat = chatMapper.getChatById(chatId);
+
+        //TODO 异步调用拿future
+        if (chat.getU1().equals(userId)) {
+            vo.setOtherSide(getSimpleUser(chat.getU2()));
+            vo.setIsU1(true);
+        } else {
+            vo.setOtherSide(getSimpleUser(chat.getU1()));
+            vo.setIsU1(false);
+        }
+        vo.setGoods(getSimpleGoods(chat.getGoodsId()));
+
+        int pageOffset = (page - 1) * size + offset;
+        PageHelper.offsetPage(pageOffset, size);
+        List<History> chatHistory = historyMapper.getChatHistory(chatId);
+
+        vo.setHistoryList(chatHistory);
+
+        return vo;
+    }
+
+    //TODO 重复
+    private SimpleGoods getSimpleGoods(Integer goodsId) {
+        log.info("从商品服务查询商品的简单信息");
+        Response<SimpleGoods> response = goodsClient.getSimpleGoods(goodsId);
+        if (response.getErrno() != 0) {
+            log.info("从商品服务获取商品信息列表失败,errno={},原因={}", response.getErrno(), response.getErrmsg());
+            return unknownGoods();
+        }
+        return response.getData();
+    }
+
+    private SimpleUser getSimpleUser(String openId) {
+        log.info("从用户服务查询用户的简单信息");
+        Response<SimpleUser> response = userClient.getSimpleUser(openId);
+        if (response.getErrno() != 0) {
+            log.info("从用户服务获取用户信息列表失败,errno={},原因={}", response.getErrno(), response.getErrmsg());
+            return unknownUser();
+        }
+        return response.getData();
+    }
+
+    private SimpleUser unknownUser() {
+        SimpleUser unknownUser = new SimpleUser();
+        unknownUser.setNickName("用户不存在");
+        unknownUser.setAvatarUrl("https://i.postimg.cc/RVbDV5fN/anonymous.png");
+        return unknownUser;
+    }
+
+    private SimpleGoods unknownGoods() {
+        SimpleGoods unknownGoods = new SimpleGoods();
+        unknownGoods.setName("商品不存在");
+        return unknownGoods;
+    }
+}

+ 3 - 4
im-service/src/main/java/io/github/nnkwrik/imservice/service/impl/IndexServiceImpl.java

@@ -96,7 +96,6 @@ public class IndexServiceImpl implements IndexService {
     }
 
 
-
     private List<LastChat> getDisplayUnread(List<LastChat> unreadMessage, int offset, int size) {
         List<LastChat> displayUnread = unreadMessage.stream()
                 .sorted((a, b) -> b.getLastMsg().getSendTime().compareTo(a.getLastMsg().getSendTime()))
@@ -160,7 +159,7 @@ public class IndexServiceImpl implements IndexService {
 
     private List<ChatIndex> setGoodsAndUser4Chat(List<ChatIndex> voList,
                                                  Map<Integer, Integer> chatGoodsMap,
-                                                 Map<Integer, String> chatUserMap){
+                                                 Map<Integer, String> chatUserMap) {
 
         //去商品服务查商品图片
         Map<Integer, SimpleGoods> simpleGoodsMap = getSimpleGoodsList(new ArrayList<>(chatGoodsMap.values()));
@@ -174,7 +173,7 @@ public class IndexServiceImpl implements IndexService {
             String userId = chatUserMap.get(vo.getLastChat().getChatId());
 
             SimpleUser simpleUser = simpleUserMap.get(userId);
-            if (simpleUser == null){
+            if (simpleUser == null) {
                 simpleUser = unknownUser();
             }
             vo.setOtherSide(simpleUser);
@@ -182,7 +181,7 @@ public class IndexServiceImpl implements IndexService {
             Integer goodsId = chatGoodsMap.get(vo.getLastChat().getChatId());
 
             SimpleGoods simpleGoods = simpleGoodsMap.get(goodsId);
-            if (simpleGoods == null){
+            if (simpleGoods == null) {
                 simpleGoods = unknownGoods();
             }
             vo.setGoods(simpleGoods);

+ 3 - 3
im-service/src/main/java/io/github/nnkwrik/imservice/service/impl/WebSocketServiceImpl.java

@@ -49,7 +49,7 @@ public class WebSocketServiceImpl implements WebSocketService {
             chatEndpoint.sendMessage(senderId, Response.fail(e.getErrno(), e.getErrmsg()));
             return;
         }
-        if (!senderId.equals(message.getSenderId())){
+        if (!senderId.equals(message.getSenderId())) {
             String msg = "发送者与ws连接中的不一致,消息发送失败";
             log.info(msg);
             chatEndpoint.sendMessage(senderId, Response.fail(Response.SENDER_AND_WS_IS_NOT_MATCH, msg));
@@ -76,7 +76,7 @@ public class WebSocketServiceImpl implements WebSocketService {
     }
 
     private void updateRedis(WsMessage message) {
-        LastChat lastChat = redisClient.hget(message.getReceiverId(), message.getGoodsId() + "");
+        LastChat lastChat = redisClient.hget(message.getReceiverId(), message.getChatId() + "");
         if (lastChat != null) {
             lastChat.setUnreadCount(lastChat.getUnreadCount() + 1);
             lastChat.setLastMsg(message);
@@ -85,7 +85,7 @@ public class WebSocketServiceImpl implements WebSocketService {
             lastChat.setUnreadCount(1);
             lastChat.setLastMsg(message);
         }
-        redisClient.hset(message.getReceiverId(), message.getGoodsId() + "", lastChat);
+        redisClient.hset(message.getReceiverId(), message.getChatId() + "", lastChat);
     }
 
     @Transactional

+ 0 - 40
im-service/src/test/java/io/github/nnkwrik/imservice/TestChatMapper.java

@@ -1,40 +0,0 @@
-package io.github.nnkwrik.imservice;
-
-import io.github.nnkwrik.imservice.dao.ChatMapper;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringRunner;
-
-/**
- * @author nnkwrik
- * @date 18/12/06 16:06
- */
-@RunWith(SpringRunner.class)
-//@SpringBootTest <-ServerEndpointExporter会报错
-@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
-public class TestChatMapper {
-
-    @Autowired
-    private ChatMapper chatMapper;
-
-    @Test
-    public void testGetChatId(){
-        String u1 = "1";
-        String u2 = "3";
-        int goodsId = 0;
-
-        //exist
-        Integer chatId = chatMapper.getChatId(u1, u2, goodsId);
-        System.out.println(chatId);
-
-        //not exist
-        Integer chatId2 = chatMapper.getChatId("21", "11", goodsId);
-        System.out.println(chatId2);
-
-    }
-
-
-
-}