Răsfoiți Sursa

feat: 调试单聊完成

qinyuyue 2 luni în urmă
părinte
comite
8cb5519088

+ 294 - 0
src/pages/chat/group-chat.vue

@@ -0,0 +1,294 @@
+<template>
+  <div class="single-page h-full w-full" style="height: 100vh">
+    <van-nav-bar @click-left="router.back()" @click-right="onClickRight">
+      <template #left>
+        <div>
+          <van-icon name="arrow-left" color="black" size="18"/>
+        </div>
+      </template>
+      <template #title>
+        <div class="text-2xl text-black-3 text-semibold">
+          <div class="inline-block w-220 line-clamp-1">
+            {{ title }}
+          </div>
+          <!-- <span class="ml-7 iconfont icon-close-remind text-black-9" style="font-size: 16px"></span> -->
+        </div>
+      </template>
+      <template #right>
+        <van-icon name="ellipsis" color="black" size="18"/>
+      </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 :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>-->
+    </template>
+    <template v-else>
+      <div class="flex-1 grid place-items-center text-black-9">
+        <div v-if="pageLoading">创建会话中...</div>
+        <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>
+            <van-button size="small" @click="initGroupId">点击重试</van-button>
+          </div>
+        </div>
+      </div>
+    </template>
+  </div>
+</template>
+<script setup>
+import ChatMessage from './chat-message'
+import ChatInput from "./chat-input";
+import {findHyperlinks} from "~/pages/chat/chat-message/link-message/handle";
+import {XYWebSocket} from "~/utils/XYWebSocket";
+import {isValidJson} from "~/utils";
+
+const route = useRoute()
+const router = useRouter()
+
+const chatsStore = useChatsStore();
+const userInfoStore = useUserInfoStore();
+
+const {userInfo} = storeToRefs(userInfoStore);
+// 单聊的标题
+const title = computed(() => route.query.groupRemark)
+
+// 聊天列表
+const chatListRef = ref(null);
+
+const pageLoading = ref(true);
+const getUserId = ref(null); // 消息接收者的用户id
+const sendUserId = computed(() => userInfo?.value.pass) // 消息发送者:当前登录用户的加密id
+const groupId = ref(route.query?.groupId); // 会话ID
+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 getChatList('init')
+  } catch (e) {
+
+  } finally {
+    pageLoading.value = false;
+  }
+}
+
+let pageNum = ref(0)
+const currConversationChatList = ref([]);
+/**
+ * 加载当前聊天信息
+ * @param type init|more
+ * @returns {Promise<void>}
+ */
+const getChatList = async (type = 'init') => {
+  try {
+    const page = type === 'init' ? 1 : pageNum.value + 1;
+    const res = await chatsStore.getChatHistory({
+      pageNum: page,
+      pageSize: 100,
+      groupId: groupId.value,
+    })
+    pageNum.value = page;
+    await handleResponse(res);
+    currConversationChatList.value = handleChatList(res.data?.data)
+    console.log(currConversationChatList.value, 'currConversationChatList')
+    if (type === 'init') await scrollToBottom()
+  } catch (e) {
+    console.error(e)
+  } finally {
+
+  }
+}
+const handleChatList = (list = []) => {
+  return (list ?? []).filter(o => isValidJson(o.messageContent)).map(o => JSON.parse(o.messageContent));
+}
+
+// 发送文本消息
+const sendTextMessage = async (text) => {
+  try {
+    console.log(text, 'sendTextMessage')
+    if (!text) return
+    let msg = {
+      groupId: groupId.value,
+      getUserId: getUserId.value,
+      sendUserId: sendUserId.value,
+      specialUserId: '',
+      messageContent: text,
+      messageType: 0,
+      noticeType: 1,
+      object: {
+        id: getLocalId()
+      }
+    }
+    const isLink = !!findHyperlinks(text)
+    if (isLink) msg.messageType = 4;
+    currConversationChatList.value.push(msg)
+    await scrollToBottom()
+    const res = await chatsStore.sendSocketMessage(msg)
+    console.log('luck:', res)
+  } catch (e) {
+    console.log(e, '2')
+  } finally {
+
+  }
+}
+
+// 选择发送图片
+const sendImageMessage = async (file) => {
+  try {
+    const formData = new FormData()
+    formData.append('uploadFile', file)
+    formData.append('asImage', true)
+    formData.append('fieldName', 'messageContent')
+    const {data} = await request('/website/tourMessage/upload', {
+      method: 'post',
+      body: formData
+    })
+
+    let msg = {
+      groupId: groupId.value,
+      getUserId: getUserId.value,
+      sendUserId: sendUserId.value,
+      specialUserId: '',
+      messageContent: data.fileUrl,
+      messageType: 1,
+      noticeType: 1,
+      object: {
+        id: getLocalId()
+      }
+    }
+    currConversationChatList.value.push(msg)
+    await scrollToBottom()
+    await chatsStore.sendSocketMessage(msg)
+  } catch (e) {
+    console.error(e, '??')
+  } finally {
+
+  }
+}
+
+const handleSendMessage = async ({type, messageContent}) => {
+  try {
+    switch (type) {
+      case 'text':
+        await sendTextMessage(messageContent)
+        break;
+      case 'image':
+        await sendImageMessage(messageContent)
+        break;
+
+      default:
+
+        break;
+    }
+
+  } catch (e) {
+
+  } finally {
+
+  }
+}
+
+const scrollToBottom = async () => {
+  setTimeout(async () => {
+    await nextTick(); // 确保DOM已经更新
+    const listElement = chatListRef.value?.$el;
+    if (listElement) {
+      const scrollContainer = listElement;
+      scrollContainer.scrollTop = scrollContainer.scrollHeight;
+    }
+  }, 200)
+};
+
+
+
+// 加载更多
+const refreshing = ref(false)
+const loadMore = async () => {
+  try {
+    refreshing.value = true
+    await getChatList('more')
+  } catch (e) { } finally {
+    refreshing.value = false
+  }
+}
+
+const onClickRight = () => {
+  navigateTo({
+    path: '/chat/set-single',
+    query: {
+      toUserId: route.query.getUserId
+    }
+  })
+}
+
+
+// 本地生成一个唯一消息id
+function getLocalId() {
+  const random = Math.floor(Math.random() * 10000)
+  return Date.now() + '' + random
+}
+
+onMounted(() => {
+  initGroupId()
+  XYWebSocket.SocketEventsBus.on(XYWebSocket.SocketEvents.chatEvent, async (chat) => {
+    const isCurrGroupId = chat.groupId && chat.groupId === groupId.value;
+    const isOtherUserMessage = chat.sendUserId && chatsStore.isRealMessage(chat.sendUserId);
+    if (isCurrGroupId && isOtherUserMessage) {
+      currConversationChatList.value.push(chat)
+      await scrollToBottom()
+    }
+  })
+})
+
+// 用户删除消息
+const delMessage = (messageId) => {
+  showConfirmDialog({
+    width: 260,
+    message: '是否删除这条消息?',
+    confirmButtonColor: '#FF9300'
+  })
+      .then(async () => {
+        const res = await request('/website/tourMessage/delMessage', {
+          method: 'post',
+          body: {
+            messageId: [messageId]
+          }
+        })
+
+        if (res && res?.success) {
+        }
+      })
+      .catch(() => {
+      })
+}
+
+definePageMeta({
+  layout: false
+})
+</script>
+<style lang="scss" scoped>
+.single-page {
+  height: 100vh;
+  display: flex;
+  flex-direction: column;
+  min-height: 0;
+}
+</style>

+ 0 - 0
src/pages/chat/single.vue → src/pages/chat/single-chat.vue


+ 12 - 10
src/pages/profile/my-news/index.vue

@@ -227,9 +227,7 @@
                       ? createTimeSplit(item?.lastMessage?.updateTime)
                       : ''
                   }"
-                  @on-chat-page="
-                    onChatPage('/chat/group', { userId: user.userId, groupId: item?.groupId })
-                  "
+                  @on-chat-page="goDetails('group', item)"
                   @on-no-bother="noBother(item)"
                   @on-is-top="onIsTop(item)"
                   @on-conv-delete="onIsShow(item)"
@@ -276,12 +274,7 @@
                 ...item,
                 updateTime: item?.lastMessage ? createTimeSplit(item?.lastMessage?.updateTime) : ''
               }"
-              @on-chat-page="
-                onChatPage('/chat/group', {
-                  userId: userInfo.userId,
-                  groupId: item?.groupId
-                })
-              "
+              @on-chat-page="goDetails('group', item)"
               @on-no-bother="noBother(item)"
               @on-is-top="onIsTop(item)"
               @on-conv-delete="onIsShow(item)"
@@ -449,12 +442,21 @@ const goDetails = (type, item) => {
     case 'single': // 单聊消息
       readMessage(item.groupId)
       navigateTo({
-        path: '/chat/single', query: {
+        path: '/chat/single-chat', query: {
           getUserId: item?.toUserId,
           groupRemark: item?.groupRemark
         }
       })
       break;
+    case 'group': // 群聊消息
+      readMessage(item.groupId)
+      navigateTo({
+        path: '/chat/group-chat', query: {
+          groupId: item?.groupId,
+          groupRemark: item?.groupRemark
+        }
+      })
+      break;
     default:
 
       break;