Răsfoiți Sursa

feat: 对接聊天功能

qinyuyue 1 lună în urmă
părinte
comite
6e962cd419
3 a modificat fișierele cu 126 adăugiri și 64 ștergeri
  1. 67 40
      src/pages/chat/group-chat.vue
  2. 55 23
      src/pages/chat/single-chat.vue
  3. 4 1
      src/stores/useChats.js

+ 67 - 40
src/pages/chat/group-chat.vue

@@ -12,9 +12,9 @@
             {{ groupInfo?.groupName }}
           </div>
           <span
-            v-if="groupMemberInfo.isNotDisturb"
-            class="ml-7 iconfont icon-close-remind text-black-9"
-            style="font-size: 16px"
+              v-if="groupMemberInfo.isNotDisturb"
+              class="ml-7 iconfont icon-close-remind text-black-9"
+              style="font-size: 16px"
           ></span>
         </div>
       </template>
@@ -24,28 +24,29 @@
     </van-nav-bar>
 
     <van-notice-bar
-      v-if="groupInfo?.groupNotice?.messageContent"
-      left-icon="volume-o"
-      mode="link"
-      :text="groupInfo?.groupNotice?.messageContent"
+        v-if="groupInfo?.groupNotice?.messageContent"
+        left-icon="volume-o"
+        mode="link"
+        :text="groupInfo?.groupNotice?.messageContent"
     ></van-notice-bar>
 
     <template v-if="showPage">
-      <van-list
-          ref="chatListRef"
-          class="flex-1 overflow-y-auto px-12 flex flex-col"
-          :finished="true"
-          finished-text=""
-      >
-        <template v-for="(message, index) in currConversationChatList" :key="index">
-          <ChatMessage :show-name="true" :message="message" ></ChatMessage>
-        </template>
-      </van-list>
-      <!--  <van-pull-refresh v-model="refreshing" @refresh="loadMore" class="flex-1">
-            </van-pull-refresh>-->
-      <!--      <div class="fixed bottom-0 left-0 right-0 w-full">-->
-      <ChatInput :operates="['image', 'share-group']" @focus="scrollToBottom" @send="handleSendMessage"></ChatInput>
-      <!--      </div>-->
+      <van-pull-refresh v-model="refreshing" @refresh="loadMore" class="flex-1">
+        <van-list
+            ref="chatListRef"
+            class="h-full overflow-y-auto px-12 flex flex-col"
+            :finished="true"
+            finished-text=""
+        >
+          <template v-for="(message, index) in currConversationChatList" :key="index">
+            <ChatMessage :show-name="true" :message="message"></ChatMessage>
+          </template>
+        </van-list>
+      </van-pull-refresh>
+      <div class="h-70 w-full bg-[#fff]"></div>
+      <div class="fixed bottom-0 left-0 right-0 w-full bg-[#fff]">
+        <ChatInput :operates="['image', 'share-group']" @focus="scrollToBottom" @send="handleSendMessage"></ChatInput>
+      </div>
     </template>
     <template v-else>
       <div class="flex-1 grid place-items-center text-black-9">
@@ -53,7 +54,7 @@
         <div v-else class="grid place-items-center">
           <div v-if="groupId">创建成功</div>
           <div v-else class="grid place-items-center">
-            <div  class="mb-10">创建会话失败</div>
+            <div class="mb-10">创建会话失败</div>
             <van-button size="small" @click="initGroupId">点击重试</van-button>
           </div>
         </div>
@@ -74,7 +75,7 @@ const router = useRouter()
 const chatsStore = useChatsStore();
 const userInfoStore = useUserInfoStore();
 
-const { userInfo } = storeToRefs(userInfoStore)
+const {userInfo} = storeToRefs(userInfoStore)
 // 群聊的标题
 const groupInfo = ref({})
 // 每个成员的信息
@@ -92,11 +93,6 @@ const showPage = computed(() => groupId.value)
 const initGroupId = async () => {
   try {
     if (!groupId.value) return;
-/*
-    pageLoading.value = true;
-    const res = await chatsStore.getCurrConversationId(getUserId.value)
-    await handleResponse(res)
-    groupId.value = res.data;*/
     await getAnnouncement()
     await getChatList('init')
 
@@ -108,6 +104,7 @@ const initGroupId = async () => {
 }
 
 let pageNum = ref(0)
+let totalCount = ref(0)
 const currConversationChatList = ref([]);
 /**
  * 加载当前聊天信息
@@ -116,16 +113,30 @@ const currConversationChatList = ref([]);
  */
 const getChatList = async (type = 'init') => {
   try {
-    const page = type === 'init' ? 1 : pageNum.value + 1;
+    let lastMessageId = null
+    let page = 1;
+    if (type === 'more') {
+      lastMessageId = getLastMessageId()
+      page = pageNum.value + 1
+    }
     const res = await chatsStore.getChatHistory({
       pageNum: page,
-      pageSize: 100,
+      pageSize: 50,
       groupId: groupId.value,
+      messageId: type === 'more' ? lastMessageId : null
     })
     pageNum.value = page;
     await handleResponse(res);
-    currConversationChatList.value = chatsStore.handleMessageList(res.data?.data)
-    if (type === 'init') await scrollToBottom()
+    let resList = chatsStore.handleMessageList(res.data?.data);
+    totalCount.value = res.data.count;
+
+    if (type === 'more') {// 滚动条位置
+      resList = resList.filter(o => o.messageId !== lastMessageId);
+      currConversationChatList.value = [...resList, ...currConversationChatList.value]
+    } else {
+      currConversationChatList.value = resList
+      await scrollToBottom()
+    }
   } catch (e) {
     console.error(e)
   } finally {
@@ -133,6 +144,14 @@ const getChatList = async (type = 'init') => {
   }
 }
 
+const getLastMessageId = () => {
+  const len = currConversationChatList.value.length;
+  if (len) {
+    return currConversationChatList.value[0]?.messageId ?? null
+  }
+  return null
+}
+
 // 发送文本消息
 const sendTextMessage = async (text) => {
   try {
@@ -237,14 +256,22 @@ const scrollToBottom = async () => {
 };
 
 
-
 // 加载更多
 const refreshing = ref(false)
 const loadMore = async () => {
   try {
     refreshing.value = true
-    await getChatList('more')
-  } catch (e) { } finally {
+    if (currConversationChatList.value.length) {
+      if(totalCount.value === currConversationChatList.value.length) {
+        // 已经加载了全部
+      } else {
+        await getChatList('more')
+      }
+    } else {
+      await getChatList('init')
+    }
+  } catch (e) {
+  } finally {
     refreshing.value = false
   }
 }
@@ -270,12 +297,12 @@ onMounted(() => {
     console.log('订阅群聊消息', chat)
     const isCurrGroupId = chat.groupId && chat.groupId === groupId.value;
     const isOtherUserMessage = chat.sendUserId && chatsStore.isRealMessage(chat.sendUserId);
-    if(isCurrGroupId) {
+    if (isCurrGroupId) {
       if (isOtherUserMessage) {
         currConversationChatList.value.push(chat)
         await scrollToBottom()
       }
-      if(!isOtherUserMessage) {
+      if (!isOtherUserMessage) {
         await getChatList('init')
       }
     }
@@ -284,8 +311,8 @@ onMounted(() => {
 
 // 查寻群公告
 async function getAnnouncement() {
-  let { data } = await request('/website/tourGroup/getGroupInfoAndMemberByGroupId', {
-    query: { groupId: groupId.value }
+  let {data} = await request('/website/tourGroup/getGroupInfoAndMemberByGroupId', {
+    query: {groupId: groupId.value}
   })
 
   if (data) {

+ 55 - 23
src/pages/chat/single-chat.vue

@@ -19,21 +19,22 @@
       </template>
     </van-nav-bar>
     <template v-if="showPage">
-      <van-list
-          ref="chatListRef"
-          class="flex-1 overflow-y-auto px-12 flex flex-col"
-          :finished="true"
-          finished-text=""
-      >
-        <template v-for="(message, index) in currConversationChatList" :key="index">
-          <ChatMessage :message="message"></ChatMessage>
-        </template>
-        <div v-if="false" class="text-[#979797] text-sm text-center mt-auto mb-10">
-          {{ followStatus }}在对方关注或回复前,最多只能发送1条信息
-        </div>
-      </van-list>
-      <!--  <van-pull-refresh v-model="refreshing" @refresh="loadMore" class="flex-1">
-            </van-pull-refresh>-->
+
+      <van-pull-refresh v-model="refreshing" @refresh="loadMore" class="flex-1">
+        <van-list
+            ref="chatListRef"
+            class="h-full overflow-y-auto px-12 flex flex-col"
+            :finished="true"
+            finished-text=""
+        >
+          <template v-for="(message, index) in currConversationChatList" :key="index">
+            <ChatMessage :message="message"></ChatMessage>
+          </template>
+          <div v-if="false" class="text-[#979797] text-sm text-center mt-auto mb-10">
+            {{ followStatus }}在对方关注或回复前,最多只能发送1条信息
+          </div>
+        </van-list>
+      </van-pull-refresh>
       <div class="h-70 w-full bg-[#fff]"></div>
       <div class="fixed bottom-0 left-0 right-0 w-full bg-[#fff]">
         <ChatInput :operates="['image']" @focus="scrollToBottom" @send="handleSendMessage"></ChatInput>
@@ -95,7 +96,8 @@ const initGroupId = async () => {
   }
 }
 
-let pageNum = ref(0)
+let pageNum = ref(0);
+let totalCount = ref(0)
 const currConversationChatList = ref([]);
 /**
  * 加载当前聊天信息
@@ -104,16 +106,30 @@ const currConversationChatList = ref([]);
  */
 const getChatList = async (type = 'init') => {
   try {
-    const page = type === 'init' ? 1 : pageNum.value + 1;
+    let lastMessageId = null
+    let page = 1;
+    if (type === 'more') {
+      lastMessageId = getLastMessageId()
+      page = pageNum.value + 1
+    }
     const res = await chatsStore.getChatHistory({
       pageNum: page,
-      pageSize: 10,
+      pageSize: 50,
       groupId: groupId.value,
+      messageId: type === 'more' ? lastMessageId : null
     })
     pageNum.value = page;
     await handleResponse(res);
-    currConversationChatList.value = chatsStore.handleMessageList(res.data?.data)
-    if (type === 'init') await scrollToBottom()
+    let resList = chatsStore.handleMessageList(res.data?.data);
+    totalCount.value = res.data.count;
+
+    if (type === 'more') {// 滚动条位置
+      resList = resList.filter(o => o.messageId !== lastMessageId);
+      currConversationChatList.value = [...resList, ...currConversationChatList.value]
+    } else {
+      currConversationChatList.value = resList
+      await scrollToBottom()
+    }
     await getFollowStatus()
   } catch (e) {
     console.error(e)
@@ -122,6 +138,14 @@ const getChatList = async (type = 'init') => {
   }
 }
 
+const getLastMessageId = () => {
+  const len = currConversationChatList.value.length;
+  if (len) {
+    return currConversationChatList.value[0]?.messageId ?? null
+  }
+  return null
+}
+
 // 发送文本消息
 const sendTextMessage = async (text) => {
   try {
@@ -240,7 +264,15 @@ const refreshing = ref(false)
 const loadMore = async () => {
   try {
     refreshing.value = true
-    await getChatList('more')
+    if (currConversationChatList.value.length) {
+      if(totalCount.value === currConversationChatList.value.length) {
+        // 已经加载了全部
+      } else {
+        await getChatList('more')
+      }
+    } else {
+      await getChatList('init')
+    }
   } catch (e) {
   } finally {
     refreshing.value = false
@@ -269,12 +301,12 @@ onMounted(() => {
     console.log('单聊页面消息订阅', chat)
     const isCurrGroupId = chat.groupId && chat.groupId === groupId.value;
     const isOtherUserMessage = chat.sendUserId && chatsStore.isRealMessage(chat.sendUserId)
-    if(isCurrGroupId) {
+    if (isCurrGroupId) {
       if (isOtherUserMessage) {
         currConversationChatList.value.push(chat)
         await scrollToBottom()
       }
-      if(!isOtherUserMessage) {
+      if (!isOtherUserMessage) {
         await getChatList('init')
       }
     }

+ 4 - 1
src/stores/useChats.js

@@ -81,7 +81,10 @@ export const useChatsStore = defineStore('chats', () => {
   const handleMessageList = (list) => {
     return (list ?? []).filter(o => isValidJson(o.messageContent)).map(o => {
       let messageContent = JSON.parse(o.messageContent)
-      messageContent.sendUserId = o.sendUserId
+      messageContent.sendUserId = o.sendUserId;
+      messageContent.messageId = o.id;
+      console.log(messageContent, 'messageContent')
+
       return messageContent
     });
   }