Эх сурвалжийг харах

feat: 单聊&群聊,发消息限制功能

suwenjiang 1 сар өмнө
parent
commit
eedd3280db

+ 13 - 7
src/pages/chat/components/chat-message/index.vue

@@ -12,9 +12,12 @@
         radius="100%"
         class="mr-8"
       ></van-image>
-      <div v-if="false" class="self-center text-sm mx-5 text-black-9">
-        <van-loading v-if="sendStatus === 'loading'" size="16" />
-        <van-icon v-if="sendStatus === 'error'" name="warning" size="16" />
+<!--      <template v-if="msg.web_message_status">
+        <div class="w-16 h-16 rounded-full bg-amber-950 text-sm grid place-content-center text-white">!</div>
+      </template>-->
+      <div v-if="msg.web_message_status" class="self-center text-sm mx-5 text-black-9">
+        <van-loading v-if="msg.web_message_status === chatsStore.WEB_MESSAGE_STATUS.loading" size="16" />
+        <van-icon v-if="msg.web_message_status === chatsStore.WEB_MESSAGE_STATUS.error" name="warning" size="16"  color="#fa9819"/>
       </div>
       <div class="flex flex-col" :class="msg.viewType ? 'items-start' : 'items-end'">
         <div v-if="showName && msg.viewType === 1" class="text-black-9 text-sm mb-2">
@@ -43,7 +46,7 @@
           ></LinkMessage>
         </div>
       </div>
-      <!--      <div class="self-center text-sm mx-5 text-black-9">发送中</div>-->
+
       <van-image
         v-if="msg.viewType === 0"
         :src="msg.headImageUrl"
@@ -65,6 +68,7 @@ import { findHyperlinks } from '~/pages/chat/components/chat-message/link-messag
 
 const userInfoStore = useUserInfoStore()
 const { userInfo } = storeToRefs(userInfoStore)
+const chatsStore = useChatsStore()
 
 const props = defineProps({
   message: Object,
@@ -75,14 +79,15 @@ const props = defineProps({
 })
 const msg = computed(() => {
   try {
-    // console.log(props.message, 'msg')
+    console.log(props.message, 'msg')
     const {
       createTime,
       getUserId,
       sendUserId,
       messageContent,
       messageType,
-      object = { headImageUrl: defaultAvatar, showName: '无名大侠' }
+      web_message_status,
+      object = { headImageUrl: defaultAvatar, showName: '无名大侠', web_message_status: chatsStore.WEB_MESSAGE_STATUS.success }
     } = props.message
     const headImageUrl = props.message.headImageUrl || object.headImageUrl
     return {
@@ -91,7 +96,8 @@ const msg = computed(() => {
       viewType: sendUserId === userInfo?.value.pass ? 0 : 1,
       createTime: createTime,
       headImageUrl: headImageUrl,
-      nickName: object.showName
+      nickName: object.showName,
+      web_message_status: object.web_message_status
     }
   } catch (e) {
     console.log(e, '??')

+ 17 - 6
src/pages/chat/group-chat.vue

@@ -69,6 +69,9 @@
         <template v-for="(message, index) in currConversationChatList" :key="index">
           <ChatMessage :show-name="true" :message="message"></ChatMessage>
         </template>
+        <div v-if="chatErrorText" class="text-[#979797] text-sm text-center mt-auto mb-10">
+          {{chatErrorText}}
+        </div>
         <!-- </div> -->
       </van-list>
       <!-- </van-pull-refresh> -->
@@ -202,15 +205,17 @@ const sendTextMessage = async (text) => {
         id: getLocalId(),
         // TODO 聊天时候改了头像昵称 会出现找不到的情况
         headImageUrl: userInfo?.value.headImageUrl,
-        showName: userInfo?.value.showName
+        showName: userInfo?.value.showName,
+        web_message_status: chatsStore.WEB_MESSAGE_STATUS.loading
       }
     }
     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)
+    const backMessage = await chatsStore.sendSocketMessage(msg);
+    const {index, message} = chatsStore.updateBackMessage(currConversationChatList.value, backMessage);
+    currConversationChatList.value[index] = message
   } catch (e) {
     // console.log(e, '2')
   } finally {
@@ -245,14 +250,17 @@ const sendImageMessage = async (file) => {
         id: getLocalId(),
         // TODO 聊天时候改了头像昵称 会出现找不到的情况
         headImageUrl: userInfo?.value.headImageUrl,
-        showName: userInfo?.value.showName
+        showName: userInfo?.value.showName,
+        web_message_status: chatsStore.WEB_MESSAGE_STATUS.loading
       }
     }
 
     closeToast()
     currConversationChatList.value.push(msg)
     await scrollToBottom()
-    await chatsStore.sendSocketMessage(msg)
+    const backMessage = await chatsStore.sendSocketMessage(msg);
+    const {index, message} = chatsStore.updateBackMessage(currConversationChatList.value, backMessage);
+    currConversationChatList.value[index] = message
   } catch (e) {
     console.error(e, '??')
   } finally {
@@ -322,6 +330,10 @@ const onClickRight = () => {
     })
 }
 
+const chatErrorText = computed(() => {
+  return chatsStore.getChatErrorText(currConversationChatList.value)
+})
+
 // 本地生成一个唯一消息id
 function getLocalId() {
   const random = Math.floor(Math.random() * 10000)
@@ -348,7 +360,6 @@ onMounted(() => {
   } catch (error) {}
 })
 
-watchEffect(() => {})
 
 // 查寻群公告
 async function getAnnouncement() {

+ 51 - 43
src/pages/chat/single-chat.vue

@@ -39,8 +39,8 @@
           <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 v-if="chatErrorText" class="text-[#979797] text-sm text-center mt-auto mb-10">
+           {{chatErrorText}}
           </div>
         </van-list>
       </van-pull-refresh>
@@ -177,7 +177,8 @@ const sendTextMessage = async (text) => {
         id: getLocalId(),
         // TODO 聊天时候改了头像昵称 会出现找不到的情况
         headImageUrl: userInfo?.value.headImageUrl,
-        showName: userInfo?.value.showName
+        showName: userInfo?.value.showName,
+        web_message_status: chatsStore.WEB_MESSAGE_STATUS.loading
       }
     }
     const isLink = !!findHyperlinks(text)
@@ -185,7 +186,9 @@ const sendTextMessage = async (text) => {
     // console.log(currConversationChatList.value, '1122')
     currConversationChatList.value.push(msg)
     await scrollToBottom()
-    await chatsStore.sendSocketMessage(msg)
+    const backMessage = await chatsStore.sendSocketMessage(msg);
+    const {index, message} = chatsStore.updateBackMessage(currConversationChatList.value, backMessage);
+    currConversationChatList.value[index] = message
   } catch (e) {
     console.log(e, '2')
   } finally {
@@ -220,13 +223,17 @@ const sendImageMessage = async (file) => {
         id: getLocalId(),
         // TODO 聊天时候改了头像昵称 会出现找不到的情况
         headImageUrl: userInfo?.value.headImageUrl,
-        showName: userInfo?.value.showName
+        showName: userInfo?.value.showName,
+        web_message_status: chatsStore.WEB_MESSAGE_STATUS.loading
       }
     }
     closeToast()
     currConversationChatList.value.push(msg)
     await scrollToBottom()
     await chatsStore.sendSocketMessage(msg)
+    const backMessage = await chatsStore.sendSocketMessage(msg);
+    const {index, message} = chatsStore.updateBackMessage(currConversationChatList.value, backMessage);
+    currConversationChatList.value[index] = message
   } catch (e) {
     console.error(e, '??')
   } finally {
@@ -253,6 +260,41 @@ const handleSendMessage = async ({ type, messageContent }) => {
   }
 }
 
+// 加载更多
+const moreLoading = ref(false)
+const moreDisabled = ref(false)
+
+const loadMore = async () => {
+  // console.warn('loadMore')
+  try {
+    moreLoading.value = true
+    if (currConversationChatList.value.length) {
+      if (totalCount.value === currConversationChatList.value.length) {
+        console.warn('已经加载了全部')
+        // 已经加载了全部
+        moreDisabled.value = true
+      } else {
+        await getChatList('more')
+      }
+    } else {
+      await getChatList('init')
+    }
+  } catch (e) {
+    // console.log(e, 'error')
+  } finally {
+    moreLoading.value = false
+  }
+}
+
+const onClickRight = () => {
+  navigateTo({
+    path: '/chat/set-single',
+    query: {
+      toUserId: route.query.getUserId,
+      groupId: groupId.value
+    }
+  })
+}
 // async
 const scrollToBottom = async () => {
   // 操作向上加载不滚动 TODO 判断用户是否有向上滑的操作更准确
@@ -289,41 +331,9 @@ const getFollowStatus = async () => {
   followStatus.value = status
 }
 
-// 加载更多
-const moreLoading = ref(false)
-const moreDisabled = ref(false)
-
-const loadMore = async () => {
-  // console.warn('loadMore')
-  try {
-    moreLoading.value = true
-    if (currConversationChatList.value.length) {
-      if (totalCount.value === currConversationChatList.value.length) {
-        console.warn('已经加载了全部')
-        // 已经加载了全部
-        moreDisabled.value = true
-      } else {
-        await getChatList('more')
-      }
-    } else {
-      await getChatList('init')
-    }
-  } catch (e) {
-    // console.log(e, 'error')
-  } finally {
-    moreLoading.value = false
-  }
-}
-
-const onClickRight = () => {
-  navigateTo({
-    path: '/chat/set-single',
-    query: {
-      toUserId: route.query.getUserId,
-      groupId: groupId.value
-    }
-  })
-}
+const chatErrorText = computed(() => {
+  return chatsStore.getChatErrorText(currConversationChatList.value)
+})
 
 // 本地生成一个唯一消息id
 function getLocalId() {
@@ -343,14 +353,12 @@ onMounted(() => {
         await scrollToBottom()
       }
       if (!isOtherUserMessage) {
-        await getChatList('init')
+        // 这里就不做处理,因为本地发送后就立马更新了currConversationChatList
       }
     }
   })
 })
 
-watchEffect(() => {})
-
 // 会话好友的信息
 const getAnnouncement = () => {
   return new Promise((resolve) => {

+ 47 - 8
src/stores/useChats.js

@@ -2,6 +2,15 @@ import { XYWebSocket } from '~/utils/XYWebSocket'
 import { isValidJson } from '~/utils'
 
 export const useChatsStore = defineStore('chats', () => {
+  const MESSAGE_TYPE = {
+    text: 0,
+    image: 1,
+    audio: 2,
+    video: 3,
+    link: 4
+  }
+  const NOTICE_TYPE = []
+
   const userInfoStore = useUserInfoStore()
   const { userInfo } = storeToRefs(userInfoStore)
 
@@ -88,14 +97,37 @@ export const useChatsStore = defineStore('chats', () => {
       })
   }
 
-  const MESSAGE_TYPE = {
-    text: 0,
-    image: 1,
-    audio: 2,
-    video: 3,
-    link: 4
+
+  const WEB_MESSAGE_STATUS = {
+    loading: 'loading',
+    success: 'success',
+    error: 'error'
+  }
+  /**
+   * 本地发送消息后,收到后端返回消息就更新本地消息 (写成hooks更好)
+   * @param list
+   * @param message
+   * @returns {{index: number, message}}
+   */
+  const updateBackMessage = (list = [], message) => {
+    const index = list.findIndex(o => o.object?.id === message?.object?.id);
+    if(index < 0) throw Error('')
+    const status = message.messageLimit > 0 && message.messageLimit < 5 ? WEB_MESSAGE_STATUS.error : WEB_MESSAGE_STATUS.success;
+    message.object.web_message_status = status
+
+    return {
+      index,
+      message
+    }
+  }
+
+  const getChatErrorText = (list = []) => {
+    const errorTextArr = ['','在对方关注或回复前,最多只能发送1条信息', '踢出群聊发消息限制', '群解散发消息限制', '封禁群聊发消息限制']
+    const errorIndex = list.findIndex(o => o.object?.web_message_status === WEB_MESSAGE_STATUS.error)
+    if(errorIndex < 0) return ''
+    const errorMessage = list[errorIndex]
+    return errorTextArr[errorMessage.messageLimit] ?? ''
   }
-  const NOTICE_TYPE = []
 
   return {
     // 注册socket
@@ -117,6 +149,13 @@ export const useChatsStore = defineStore('chats', () => {
 
     // 排除自己发的消息
     isRealMessage,
-    handleMessageList
+    handleMessageList,
+
+
+    WEB_MESSAGE_STATUS,
+    updateBackMessage,
+
+
+    getChatErrorText
   }
 })

+ 0 - 1
src/utils/XYWebSocket.ts

@@ -8,7 +8,6 @@ export namespace XYWebSocket {
         public socketUrl: string;
         public options: SocketOptions = {
             apiTimeout: 10, // 接口请求超时 s
-            connectionTimeout: 10 * 1000, // 超时连接 ms
             maxRetries: 5, // 最大重连次数
         };
         private eventPoll: Map<string, SocketResponseType> = new Map();