Browse Source

fix: 1.修改聊天的额bug 单聊的创建群 单聊的的设置,添加用户的搜索,群聊的不能下滑查看历史记录的问题

suwenjiang 1 month ago
parent
commit
779fb62680

+ 2 - 1
.env.development

@@ -2,7 +2,8 @@ VITE_APP_ENV=development
 
 # VITE_APP_BASE_URL=https://service.xiaoyaotravel.com/api/
 # VITE_APP_BASE_URL=http://101.126.146.250:8082/
-# 测试服
+# VITE_APP_IM_URL=ws://101.126.146.250:8082/system/message
+# # 测试服
 
 
 

+ 6 - 0
src/assets/img/chat/book.svg

@@ -0,0 +1,6 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="Book (&#228;&#185;&#166;&#231;&#177;&#141;)">
+<path id="Vector" d="M4 20C4 18 4 5 4 5C4 3.34315 5.4327 2 7.2 2H20V18C20 18 9.99075 18 7.2 18C4.68112 18 4 18.3421 4 20Z" fill="#FF9300" stroke="#FF9300" stroke-width="0.666667" stroke-linejoin="round"/>
+<path id="Vector_2" fill-rule="evenodd" clip-rule="evenodd" d="M6 22H20V18H6C4.89543 18 4 18.8954 4 20C4 21.1046 4.89543 22 6 22Z" stroke="#FF9300" stroke-width="0.666667" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+</svg>

+ 9 - 0
src/assets/img/chat/scan.svg

@@ -0,0 +1,9 @@
+<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="scan">
+<g id="union">
+<path d="M13.5 3.9375H4.5V7.3125H3.375V3.9375C3.375 3.31615 3.87872 2.8125 4.5 2.8125H13.5C14.1213 2.8125 14.625 3.31615 14.625 3.9375V7.3125H13.5V3.9375Z" fill="white"/>
+<path d="M3.375 10.6875H4.5V14.0625H13.5V10.6875H14.625V14.0625C14.625 14.6838 14.1213 15.1875 13.5 15.1875H4.5C3.87872 15.1875 3.375 14.6838 3.375 14.0625V10.6875Z" fill="white"/>
+<path d="M15.75 8.4375V9.5625H2.25V8.4375H15.75Z" fill="white"/>
+</g>
+</g>
+</svg>

+ 20 - 3
src/components/Chat/Search.vue

@@ -7,10 +7,9 @@
         v-model="searchString"
         class="ml-5 w-[80%] h-full pl-10 text-[13px]"
         :placeholder="placeholder"
-        @keydown.enter="$emit('search')"
+        @keydown.enter.stop="handleKeyDown"
         style="outline: none; background: none"
       />
-      <!--  @change="$emit('search')" -->
       <button
         @click="$emit('search')"
         class="h-full border-l-[1px] flex justify-center items-center w-66 shrink-0 rounded-r-full"
@@ -25,6 +24,8 @@
 
 <script setup>
 const searchString = defineModel('searchString')
+const isThrottled = ref(false)
+
 defineProps({
   placeholder: {
     type: String,
@@ -32,7 +33,23 @@ defineProps({
   }
 })
 
-defineEmits(['search'])
+const emit = defineEmits(['search'])
+
+function handleKeyDown(event) {
+  console.log(!isThrottled.value)
+
+  if (event.key === 'Enter' && !isThrottled.value) {
+    emit('search')
+
+    // 启动节流
+    isThrottled.value = true
+
+    // 1000ms 后解除节流
+    setTimeout(() => {
+      isThrottled.value = false
+    }, 3000)
+  }
+}
 </script>
 
 <style lang="scss" scoped></style>

+ 0 - 2
src/components/Profile/News/GroupChat.vue

@@ -18,7 +18,6 @@
           {{ itemData?.groupRemark }}
         </h1>
         <p class="line-clamp-1 w-full h-20 text-base text-black/[0.6] leading-3xl">
-          <!-- {{ messageContentParse(itemData?.lastMessage?.messageContent) }} -->
           {{ itemData?.lastMessage ? itemData?.lastMessage?.messageContent?.messageContent : '' }}
         </p>
       </div>
@@ -67,7 +66,6 @@
 </template>
 
 <script setup>
-import { messageContentParse } from '~/utils/detalTime.js'
 const props = defineProps({
   itemData: {
     type: Object,

+ 57 - 58
src/pages/chat/components/chat-input/index.vue

@@ -3,40 +3,38 @@
     <div class="input-box">
       <div v-if="false" class="mr-12">语音todo</div>
       <div
-          @click="openTool('operate')"
-          class="iconfont icon-close-one rotate-45 mr-12 text-black-6"
-          style="font-size: 32px"
+        @click="openTool('operate')"
+        class="iconfont icon-close-one rotate-45 mr-12 text-black-6"
+        style="font-size: 32px"
       ></div>
       <div
-          @click="openTool('emoji')"
-          class="iconfont icon-slightly-smiling-face text-black-6 mr-12"
-          style="font-size: 32px"
+        @click="openTool('emoji')"
+        class="iconfont icon-slightly-smiling-face text-black-6 mr-12"
+        style="font-size: 32px"
       ></div>
       <div class="input-box__textarea mr-12" id="input-kary">
         <van-field
-            v-model="inputValue"
-            autosize
-            ref="inputRef"
-            rows="1"
-            type="textarea"
-            placeholder="请输入"
-            @focus="handleFocus"
-            @blur="handleBlur"
+          v-model="inputValue"
+          autosize
+          ref="inputRef"
+          rows="1"
+          type="textarea"
+          placeholder="请输入"
+          @focus="handleFocus"
+          @blur="handleBlur"
         />
       </div>
-      <van-button size="small" type="warning" @click="sendTextMessage"> 发 送</van-button>
+      <van-button size="small" type="warning" @click="sendTextMessage">发 送</van-button>
     </div>
     <div v-show="showTool" class="px-20 py-8">
       <div class="operate-box" v-show="currTool === 'operate'">
-        <div v-for="(operate, i) in showOperateList"
-             :key="i"
-             @click="handleOperate(operate)"
-        >
+        <div v-for="(operate, i) in showOperateList" :key="i" @click="handleOperate(operate)">
           <div
-              class="w-54 h-54 active:bg-[#FF9300]/[0.1] bg-[#F3F3F3] shrink-0 rounded-full mb-5 flex justify-center items-center">
+            class="w-54 h-54 active:bg-[#FF9300]/[0.1] bg-[#F3F3F3] shrink-0 rounded-full mb-5 flex justify-center items-center"
+          >
             <span
-                :class="`iconfont ${operate.icon} text-black-6 active:text-[#FF9300] `"
-                style="font-size: 32px"
+              :class="`iconfont ${operate.icon} text-black-6 active:text-[#FF9300] `"
+              style="font-size: 32px"
             ></span>
           </div>
           <p class="text-sm w-full text-center">{{ operate.title }}</p>
@@ -44,10 +42,10 @@
       </div>
       <div class="emoji-box h-144 overflow-y-auto" v-show="currTool === 'emoji'">
         <div
-            v-for="(item, index) in emojiJson"
-            :key="index"
-            @click="selectEmoji(item, index)"
-            class="active:bg-[#ddd] text-4xl w-26 aspect-[1/1] grid place-items-center"
+          v-for="(item, index) in emojiJson"
+          :key="index"
+          @click="selectEmoji(item, index)"
+          class="active:bg-[#ddd] text-4xl w-26 aspect-[1/1] grid place-items-center"
         >
           <div @click="selectEmoji(index)" v-html="item.emoji"></div>
         </div>
@@ -57,20 +55,20 @@
 </template>
 
 <script setup>
-import emojiJson from "~/components/Profile/News/emoji";
+import emojiJson from '~/components/Profile/News/emoji'
 
 const props = defineProps({
   operates: {
     type: Array,
-    default: () => ['image']// ['image', 'share-group']
-  },
+    default: () => ['image'] // ['image', 'share-group']
+  }
 })
 const emit = defineEmits(['send', 'focus', 'blur'])
 
 const inputValue = ref('')
-const inputRef = ref(null);
+const inputRef = ref(null)
 
-const chatInputCompRef = ref(null);
+const chatInputCompRef = ref(null)
 const operateList = [
   {
     title: '相册',
@@ -84,13 +82,13 @@ const operateList = [
     isShow: props.operates.includes('share-group'),
     fn: 'shareGroupChat'
   }
-];
+]
 
 const showOperateList = computed(() => {
-  return operateList.filter(o => o.isShow)
+  return operateList.filter((o) => o.isShow)
 })
 
-const {open, onChange: uploadImage} = useFileDialog({
+const { open, onChange: uploadImage } = useFileDialog({
   accept: 'image/*'
 })
 
@@ -99,22 +97,20 @@ const handleOperate = (operate) => {
     switch (operate.fn) {
       case 'uploadImage':
         open()
-        break;
+        break
       case 'shareGroupChat':
         console.log('分享群聊')
         showToast('研发中,敬请期待~')
-        break;
+        break
     }
-  } catch (e) {
-
-  }
+  } catch (e) {}
 }
 
 uploadImage(async (files) => {
   if (!files.length) return
 
   console.log(files[0], 'files[0]files[0]')
-  const {type, size} = files[0];
+  const { type, size } = files[0]
   if (!['image/jpeg', 'image/png', 'image/gif'].includes(type)) {
     showToast('请上传图片')
   }
@@ -144,23 +140,26 @@ const sendTextMessage = () => {
       showToast('发送内容不能为空!')
       return
     }
+
     emit('send', {
       type: 'text',
       messageContent: inputValue.value
     })
+
     inputValue.value = ''
-  } catch (e) {
+    // if (inputValue.value <= 2000) {
 
-  }
+    // } else {
+    // showToast('发送内容不能超过2000字!')
+    // }
+  } catch (e) {}
 }
 const selectEmoji = async (item, index) => {
   try {
     const position = getInputPosition()
-    const str = inputValue.value;
+    const str = inputValue.value
     inputValue.value = `${str.slice(0, position)}${emojiJson[index].emoji}${str.slice(position)}`
-  } catch (e) {
-
-  }
+  } catch (e) {}
 }
 
 const showTool = ref(false)
@@ -179,8 +178,8 @@ const handleBlur = () => {
 const getInputPosition = () => {
   try {
     if (!inputValue.value) return 0
-    const el = inputRef.value?.$el.querySelector('input, textarea');
-    if (!el) return inputValue.value.length - 1;
+    const el = inputRef.value?.$el.querySelector('input, textarea')
+    if (!el) return inputValue.value.length - 1
     return el.selectionStart
   } catch (e) {
     console.log(e, '??')
@@ -189,18 +188,18 @@ const getInputPosition = () => {
 
 // 判断是否点击的非输入框
 const handleClickOutside = (event) => {
-  const chatInputCompEl = chatInputCompRef.value;
-  const isChatInputCompEl = chatInputCompEl.contains(event.target);
+  const chatInputCompEl = chatInputCompRef.value
+  const isChatInputCompEl = chatInputCompEl.contains(event.target)
 
   if (!isChatInputCompEl) {
     showTool.value = false
     inputRef.value.$el.blur()
   }
-};
+}
 onMounted(() => {
-  useEventListener('click', handleClickOutside, {target: document})
-  useEventListener('mousedown', handleClickOutside, {target: document})
-  useEventListener('touchstart', handleClickOutside, {target: document})
+  useEventListener('click', handleClickOutside, { target: document })
+  useEventListener('mousedown', handleClickOutside, { target: document })
+  useEventListener('touchstart', handleClickOutside, { target: document })
 
   if (process.env.NODE_ENV === 'development') {
     useEventListener('keyup', (event) => {
@@ -215,7 +214,7 @@ onMounted(() => {
 <style scoped lang="scss">
 .chat-input-comp {
   width: 100%;
-  border-top: 1px solid #E7E7E7;
+  border-top: 1px solid #e7e7e7;
 
   .input-box {
     width: 100%;
@@ -228,9 +227,9 @@ onMounted(() => {
 
     .input-box__textarea {
       flex: 1;
-      background: #F3F3F3;
+      background: #f3f3f3;
       border-radius: 20px;
-      border: 1px solid #DCDCDC;
+      border: 1px solid #dcdcdc;
       padding: 5px 10px;
     }
   }
@@ -262,4 +261,4 @@ onMounted(() => {
   max-height: 100px;
   overflow-y: auto;
 }
-</style>
+</style>

+ 54 - 39
src/pages/chat/components/chat-message/index.vue

@@ -1,54 +1,70 @@
 <template v-if="msg">
   <div class="chat-message" :class="msg.viewType ? 'chat-message--accept' : 'chat-message--send'">
-    <div class="h-20 grid place-items-center text-center text-sm text-[#000]/40 mb-16">{{ msg.createTime }}</div>
+    <div class="h-20 grid place-items-center text-center text-sm text-[#000]/40 mb-16">
+      {{ msg.createTime }}
+    </div>
     <div class="chat-message__content">
       <van-image
-          v-if="msg.viewType === 1"
-          :src="msg.headImageUrl"
-          width="40px"
-          height="40px"
-          radius="100%"
-          class="mr-8"
+        v-if="msg.viewType === 1"
+        :src="msg.headImageUrl"
+        width="40px"
+        height="40px"
+        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"/>
+      <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" />
       </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">{{ msg.nickName }}</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">
+          {{ msg.nickName }}
+        </div>
         <div class="flex-grow-0 w-fit">
-          <TextMessage v-if="msg.type === 'text'" :message-content="msg.messageContent"
-                       :view-type="msg.viewType"></TextMessage>
-          <ImageMessage v-if="msg.type === 'image'" :message-content="msg.messageContent"
-                        :view-type="msg.viewType"></ImageMessage>
-          <AudioMessage v-if="msg.type === 'audio'" :message-content="msg.messageContent"
-                        :view-type="msg.viewType"></AudioMessage>
-          <LinkMessage v-if="msg.type === 'link'" :message-content="msg.messageContent"
-                       :view-type="msg.viewType"></LinkMessage>
+          <TextMessage
+            v-if="msg.type === 'text'"
+            :message-content="msg.messageContent"
+            :view-type="msg.viewType"
+          ></TextMessage>
+          <ImageMessage
+            v-if="msg.type === 'image'"
+            :message-content="msg.messageContent"
+            :view-type="msg.viewType"
+          ></ImageMessage>
+          <AudioMessage
+            v-if="msg.type === 'audio'"
+            :message-content="msg.messageContent"
+            :view-type="msg.viewType"
+          ></AudioMessage>
+          <LinkMessage
+            v-if="msg.type === 'link'"
+            :message-content="msg.messageContent"
+            :view-type="msg.viewType"
+          ></LinkMessage>
         </div>
       </div>
-<!--      <div class="self-center text-sm mx-5 text-black-9">发送中</div>-->
+      <!--      <div class="self-center text-sm mx-5 text-black-9">发送中</div>-->
       <van-image
-          v-if="msg.viewType === 0"
-          :src="msg.headImageUrl"
-          width="40px"
-          height="40px"
-          radius="100%"
-          class="ml-8"
+        v-if="msg.viewType === 0"
+        :src="msg.headImageUrl"
+        width="40px"
+        height="40px"
+        radius="100%"
+        class="ml-8"
       ></van-image>
     </div>
   </div>
 </template>
 <script setup>
-import defaultAvatar from "assets/img/default_avatar.png";
-import TextMessage from "~/pages/chat/components/chat-message/text-message/index.vue";
-import ImageMessage from "~/pages/chat/components/chat-message/image-message/index.vue";
-import AudioMessage from "~/pages/chat/components/chat-message/audio-message/index.vue";
-import LinkMessage from "~/pages/chat/components/chat-message/link-message/index.vue";
-import {findHyperlinks} from "~/pages/chat/components/chat-message/link-message/handle";
+import defaultAvatar from '@/assets/img/default_avatar.png'
+import TextMessage from '~/pages/chat/components/chat-message/text-message/index.vue'
+import ImageMessage from '~/pages/chat/components/chat-message/image-message/index.vue'
+import AudioMessage from '~/pages/chat/components/chat-message/audio-message/index.vue'
+import LinkMessage from '~/pages/chat/components/chat-message/link-message/index.vue'
+import { findHyperlinks } from '~/pages/chat/components/chat-message/link-message/handle'
 
-const userInfoStore = useUserInfoStore();
-const {userInfo} = storeToRefs(userInfoStore);
+const userInfoStore = useUserInfoStore()
+const { userInfo } = storeToRefs(userInfoStore)
 
 const props = defineProps({
   message: Object,
@@ -56,7 +72,7 @@ const props = defineProps({
     type: Boolean,
     default: false
   }
-});
+})
 const msg = computed(() => {
   try {
     // console.log(props.message, 'msg')
@@ -66,7 +82,7 @@ const msg = computed(() => {
       sendUserId,
       messageContent,
       messageType,
-      object = {headImageUrl: defaultAvatar, showName: '无名大侠'}
+      object = { headImageUrl: defaultAvatar, showName: '无名大侠' }
     } = props.message
     return {
       messageContent: messageContent,
@@ -102,7 +118,6 @@ onMounted(() => {
   // handleSendStatus()
 })
 
-
 const getMessageType = (messageType, messageContent) => {
   const types = ['text', 'image', 'audio', 'video', 'link']
   if (messageType === 0 && findHyperlinks(messageContent)) return types[4]
@@ -130,4 +145,4 @@ const getMessageType = (messageType, messageContent) => {
     }
   }
 }
-</style>
+</style>

+ 2 - 3
src/pages/chat/create-group.vue

@@ -95,8 +95,9 @@
           >
             <div class="w-24 h-24 shrink-0 mr-6">
               <img
+                v-if="subItem?.typeIcon"
                 class="w-full h-full object-cover"
-                :src="item?.typeIcon ? item?.typeIcon : city"
+                :src="subItem?.typeIcon"
                 alt=""
               />
             </div>
@@ -168,8 +169,6 @@
 </template>
 
 <script setup>
-import city from '~/assets/img/chat/city-one.svg'
-
 const userInfoStore = useUserInfoStore()
 const { userInfo } = storeToRefs(userInfoStore)
 

+ 13 - 13
src/pages/chat/group-add.vue

@@ -11,15 +11,15 @@
         title="暂无数据"
         top="100"
       />
-
-      <van-list
-        v-model:loading="loading"
-        error-text="获取失败"
-        finished-text="-- 没有更多了 --"
-        :finished="finished"
-        :immediate-check="false"
-      >
-        <div style="height: calc(100vh - 170px)">
+      <div style="height: calc(100vh - 170px)" class="overflow-y-auto">
+        <van-list
+          v-model:loading="loading"
+          class="h-full"
+          error-text="获取失败"
+          finished-text="-- 没有更多了 --"
+          :finished="finished"
+          :immediate-check="false"
+        >
           <van-checkbox-group v-model="checked">
             <!-- <van-index-bar
               highlight-color="#FD9A00"
@@ -79,8 +79,8 @@
             <!-- </template> -->
             <!-- </van-index-bar> -->
           </van-checkbox-group>
-        </div>
-      </van-list>
+        </van-list>
+      </div>
     </van-pull-refresh>
 
     <div
@@ -236,7 +236,7 @@ async function handleCreateGroup() {
       message: '准备开始群聊...',
       duration: 100000
     })
-    let { data } = request('/website/tourMember/invite', {
+    let { data } = await request('/website/tourMember/invite', {
       method: 'post',
       body: {
         groupId: route.query.groupId,
@@ -245,7 +245,7 @@ async function handleCreateGroup() {
     })
     if (data) {
       navigateTo({
-        path: '/chat/group',
+        path: '/chat/group-chat',
         query: data,
         replace: true
       })

+ 12 - 9
src/pages/chat/group-chat.vue

@@ -32,21 +32,20 @@
 
     <template v-if="showPage">
       <!-- <van-pull-refresh v-model="refreshing" @refresh="loadMore" class="flex-1"> -->
-      <!-- <van-list
+      <van-list
         ref="chatListRef"
         class="h-full overflow-y-auto px-12 flex flex-col"
         :finished="true"
         finished-text=""
-      > -->
-      <!-- <van-pull-refresh v-model="refreshing" @refresh="loadMore" class="flex-1"> -->
-      <div ref="chatListRef" class="h-full overflow-y-auto px-12 flex flex-col">
+      >
+        <!-- <div ref="chatListRef" class="h-full overflow-y-auto px-12 flex flex-col"> -->
         <template v-for="(message, index) in currConversationChatList" :key="index">
           <ChatMessage :show-name="true" :message="message"></ChatMessage>
         </template>
-      </div>
-      <!-- </van-list> -->
+        <!-- </div> -->
+      </van-list>
       <!-- </van-pull-refresh> -->
-      <div class="h-70 w-full bg-[#fff]"></div>
+      <div class="h-70 w-full bg-[#fff] border"></div>
       <div class="fixed bottom-0 left-0 right-0 w-full bg-[#fff]">
         <ChatInput
           :operates="['image', 'share-group']"
@@ -244,12 +243,15 @@ const handleSendMessage = async ({ type, messageContent }) => {
 }
 
 const scrollToBottom = async () => {
+  if (refreshing.value) return
   setTimeout(async () => {
     await nextTick() // 确保DOM已经更新
     const listElement = chatListRef.value?.$el
     if (listElement) {
       const scrollContainer = listElement
+
       scrollContainer.scrollTop = scrollContainer.scrollHeight
+      console.log(scrollContainer.scrollTop, '6666')
     }
   }, 200)
 }
@@ -308,16 +310,17 @@ onMounted(() => {
   } catch (error) {}
 })
 
+watchEffect(() => {})
+
 // 查寻群公告
 async function getAnnouncement() {
   let { data } = await request('/website/tourGroup/getGroupInfoAndMemberByGroupId', {
     query: { groupId: groupId.value }
   })
-  console.log(data.memberList)
 
   if (data) {
     groupInfo.value = data
-    if (Array.isArray(data.memberList) && data.memberList?.lenght) {
+    if (Array.isArray(data.memberList) && data?.memberList?.length) {
       data.memberList.map((el) => {
         if (el.userId == userInfo.value.userId) {
           groupMemberInfo.value = el

+ 97 - 75
src/pages/chat/group-square.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="w-full h-full">
     <ChatHeaderBar title="群聊广场" />
-
+    <!-- <van-pull-refresh v-model="refreshing" @refresh="onRefresh"> -->
     <ChatSearch
       placeholder="搜索你想找的群聊"
       v-model:searchString="groupName"
@@ -9,47 +9,48 @@
       @search="search"
     ></ChatSearch>
 
-    <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
-      <div class="h-[80vh]">
-        <van-tabs
-          class="w-full pl-0"
-          title-active-color="#FF9300"
-          title-inactive-color="#333333"
-          v-model:active="active"
-          @click-tab="onClickTab"
-          style="--van-tabs-bottom-bar-color: #ff9300; --van-tabs-bottom-bar-width: 16px"
-          swipeable
+    <div class="w-full h-[80vh] box-border bg-white">
+      <van-tabs
+        class="w-full pl-0"
+        title-active-color="#FF9300"
+        title-inactive-color="#333333"
+        v-model:active="active"
+        @click-tab="onClickTab"
+        style="--van-tabs-bottom-bar-color: #ff9300; --van-tabs-bottom-bar-width: 16px"
+        swipeable
+      >
+        <van-tab
+          style="height: calc(100vh - 280px)"
+          class="border-t-[1px] overflow-y-auto"
+          v-for="(el, i) in squareTabList"
+          :key="el.id"
+          :title="el?.typeName"
         >
-          <van-tab
-            class="border-t-[1px]"
-            v-for="(el, i) in squareTabList"
-            :key="el.id"
-            :title="el?.typeName"
-          >
-            <div class="w-full h-full pl-16 box-border">
-              <Empty v-if="!groupSquareList?.length && !loading" title="暂无群聊" top="100" />
-              <!-- v-model:loading="loading" -->
-              <!-- <van-list
-                v-else
-                v-model:loading="loading"
-                error-text="获取失败"
-                finished-text=""
-                :finished="finished"
-                :immediate-check="false"
-                @load="getLoadList"
-              > -->
+          <div class="w-full mb-15 box-border h-full pl-16">
+            <Empty v-if="!groupSquareList?.length && !loading" title="暂无群聊" top="100" />
+
+            <van-list
+              v-else
+              class="h-full"
+              v-model:loading="loading"
+              error-text="获取失败"
+              finished-text=""
+              :offset="60"
+              :finished="finished"
+              :immediate-check="false"
+              @load="getLoadList"
+            >
               <template v-if="queryParams.groupTypeId == el.id">
                 <van-cell
                   v-for="(item, index) in groupSquareList"
                   :key="item.id"
                   style="--van-cell-horizontal-padding: 0; padding: 16px 16px 16px 0"
                   center
-                  class="border-b-[1px] py-16 pl-0"
+                  class="border-b-[1px] border-[#E7E7E7] py-16 pl-0"
                 >
                   <template #icon>
-                    <div style="" class="h-48 w-48 mr-12 overflow-hidden">
-                      <!-- <MultiHeader v-if="item?.userList" :size="48" :img-urls="[item?.userList]" />
-                      <MultiHeader v-else :size="48" :img-urls="[defaultAvatar]" /> -->
+                    <div class="h-48 w-48 mr-12 overflow-hidden">
+                      <MultiHeader v-if="item?.userList" :size="48" :imgUrls="item?.userList" />
                     </div>
                   </template>
                   <template #title>
@@ -78,6 +79,7 @@
                   </template>
                   <template #value>
                     <van-button
+                      v-if="item?.codeShowStatus"
                       size="small"
                       :color="chageState(item.codeShowStatus).color"
                       round
@@ -91,17 +93,17 @@
                   </template>
                 </van-cell>
               </template>
-              <!-- </van-list> -->
-            </div>
-          </van-tab>
-        </van-tabs>
-      </div>
-    </van-pull-refresh>
-
-    <div class="fixed w-full p-16 pb-40 bottom-0 left-0 bg-white">
+            </van-list>
+          </div>
+        </van-tab>
+      </van-tabs>
+    </div>
+    <!-- </van-pull-refresh> -->
+
+    <div class="fixed border w-full p-16 pb-40 bottom-0 left-0 bg-white">
       <van-button
         size="large"
-        style="background: #fa8446; margin-top: 30px"
+        style="background: #fa8446"
         color="#fff"
         round
         block
@@ -143,6 +145,8 @@ const queryParams = reactive({
 // 获取切换的数据
 const onClickTab = ({ title }) => {
   queryParams.groupTypeId = squareTabList.value.find((item) => item.typeName == title).id
+
+  console.log(queryParams.groupTypeId, ' queryParams.groupTypeId')
 }
 
 // 加入群聊
@@ -226,6 +230,14 @@ function chageState(state) {
   return item
 }
 
+const changeHeadImage = (headerList) => {
+  let headImageList = headerList
+    .slice(0, 9)
+    .map((el) => (el?.headImageUrl ? el?.headImageUrl : defaultAvatar))
+
+  return headImageList
+}
+
 // 获取数据
 const getList = async () => {
   try {
@@ -238,27 +250,22 @@ const getList = async () => {
       }
     })
 
-    dataList.map((el) => {
-      console.log(el?.userList, 'userList')
-
-      if (Array.isArray(el?.userList) && el?.userList?.length > 0) {
-        console.log(el?.userList, 'eluserList')
-        el = {
-          ...el,
-          userList: [...changeHeadImage(el?.userList)]
-        }
-      } else {
-        el = {
-          ...el,
-          userList: [defaultAvatar]
-          // userList:
-        }
-      }
-
-      return el
-    })
-    console.log(dataList, '555')
     if (Array.isArray(dataList) && dataList?.length) {
+      dataList = dataList.map((el) => {
+        if (Array.isArray(el?.userList) && el?.userList?.length > 0) {
+          el = {
+            ...el,
+            userList: changeHeadImage(el?.userList)
+          }
+
+          return el
+        } else {
+          return {
+            ...el,
+            userList: [defaultAvatar]
+          }
+        }
+      })
       groupSquareList.value = groupSquareList.value.concat(dataList)
     } else {
       groupSquareList.value = []
@@ -266,11 +273,11 @@ const getList = async () => {
 
     loading.value = false
     refreshing.value = false
-    // if (groupSquareList.value.length >= totalCount) {
-    //   finished.value = true
-    // } else {
-    finished.value = false
-    // }
+    if (groupSquareList.value.length >= totalCount) {
+      finished.value = true
+    } else {
+      finished.value = false
+    }
   } catch (err) {
   } finally {
     refreshing.value = false
@@ -278,14 +285,6 @@ const getList = async () => {
   }
 }
 
-const changeHeadImage = (headerList) => {
-  let headImageList = headerList
-    .slice(0, 9)
-    .map((el) => (el?.headImageUrl ? el?.headImageUrl : defaultAvatar))
-
-  return headImageList
-}
-
 // 加群聊
 const getGroupAdd = async (groupId) => {
   let { data } = await request('/website/tourMember/invite', {
@@ -320,6 +319,29 @@ const onRefresh = () => {
   getList()
 }
 
+watch(
+  [() => queryParams.groupTypeId],
+  () => {
+    groupSquareList.value = []
+    getList()
+  },
+  {
+    immediate: true
+  }
+)
+
+watch(
+  active,
+  (newVla, oldVla) => {
+    if (squareTabList.value[newVla]) {
+      queryParams.groupTypeId = squareTabList.value[newVla].id
+    }
+  },
+  {
+    immediate: true
+  }
+)
+
 useSeoMeta({
   title: '群聊广场'
 })

+ 26 - 67
src/pages/chat/set-single.vue

@@ -29,7 +29,14 @@
         </van-col>
         <van-col style="width: 54px" span="4" class="mb-12 mr-10">
           <div
-            @click="navigateTo('/chat/single-add')"
+            @click="
+              navigateTo({
+                path: '/chat/single-add',
+                query: {
+                  toUserId
+                }
+              })
+            "
             class="w-40 h-40 flex justify-center items-center bg-[#F3F3F3] rounded-full mx-auto overflow-hidden mb-4"
           >
             <span class="iconfont icon-plus text-black-6" style="font-size: 24px"></span>
@@ -66,7 +73,7 @@
       <van-cell size="large" title="查找聊天记录" is-link @click="findChatHistory"></van-cell>
     </van-cell-group>
     <van-cell-group style="margin-bottom: 12px" class="box-border" inset>
-      <van-cell :clickable="false" size="large" title="消息打扰" is-link>
+      <van-cell :clickable="false" size="large" title="消息打扰" is-link>
         <template #right-icon>
           <van-switch
             :active-value="1"
@@ -124,9 +131,6 @@
   </div>
 </template>
 <script setup>
-const chatStore = useChatStore()
-const { ws, chatList } = storeToRefs(chatStore)
-
 const route = useRoute()
 
 definePageMeta({
@@ -134,18 +138,15 @@ definePageMeta({
 })
 
 onMounted(() => {
-  chatStore.reqChatList()
+  getFriendInfo()
 })
 
+// 对方的id
+const toUserId = computed(() => route.query.toUserId ?? '')
+
 const isNotDisturb = ref(0)
 const isTop = ref(0)
-
-const itemData = computed(() => {
-  let item = chatList.value.filter((el) => el.toUserId == route.query.toUserId)[0]
-  isNotDisturb.value = item?.isNotDisturb
-  isTop.value = item?.isTop
-  return item
-})
+const itemData = ref({})
 
 const dialogParmas = reactive({
   show: false,
@@ -155,6 +156,17 @@ const dialogParmas = reactive({
   subTitle: ''
 })
 
+// 获取对方的信息 根据会话id
+const getFriendInfo = async () => {
+  const { data } = await request('/website/tourism/fans/getTourMemberList')
+  const { list } = data || {}
+  if (Array.isArray(list) && list?.length) {
+    itemData.value = list.filter((el) => el.toUserId == toUserId.value)[0]
+    isNotDisturb.value = itemData.value
+    isTop.value = itemData.value
+  }
+}
+
 // 弹窗确认的事件
 const confirm = async () => {
   changeGroupName({ remark: dialogParmas.remark })
@@ -194,7 +206,7 @@ const changeGroupName = async (body) => {
     })
 
     if (res && res?.success) {
-      chatStore.reqChatList()
+      getFriendInfo()
       dialogParmas.remark = ''
       dialogParmas.show = false
     }
@@ -274,59 +286,6 @@ const clearChatHistory = () => {
     .catch(() => {})
 }
 
-// const list = reactive([
-//   {
-//     title: '设置备注名',
-//     // icon: setting,
-//     // icon: 'icon-setting-one',
-//     isLink: true,
-//     vModel: null,
-//     fn: modifyNoteName,
-//     value: ''
-//   },
-//   {
-//     title: '查找聊天记录',
-//     value: '',
-//     // icon: 'icon-log',
-//     isLink: true,
-//     vModel: null,
-//     fn: findChatHistory
-//   },
-//   {
-//     title: '消息面打扰',
-//     value: '',
-
-//     // icon: 'icon-close-remind',
-//     isLink: false,
-//     vModel: isNotDisturb.value,
-//     fn: notDisturb
-//   },
-//   {
-//     title: '置顶聊天',
-//     value: '',
-//     // icon: 'icon-set-top',
-//     isLink: false,
-//     vModel: isTop.value,
-//     fn: topChat
-//   },
-//   {
-//     title: '举报该用户',
-//     value: '',
-//     // icon: 'icon-jubaoguanli',
-//     isLink: true,
-//     vModel: null,
-//     fn: reportUser
-//   },
-//   {
-//     title: '清空聊天记录',
-//     value: '',
-//     // icon: 'icon-delete-one',
-//     isLink: true,
-//     vModel: null,
-//     fn: clearChatHistory
-//   }
-// ])
-
 useSeoMeta({
   title: '我的消息'
 })

+ 3 - 1
src/pages/chat/set.vue

@@ -401,8 +401,9 @@
           >
             <div class="w-24 h-24 shrink-0 mr-6">
               <img
+                v-if="subItem?.typeIcon"
                 class="w-full h-full object-cover"
-                :src="item?.typeIcon ? item?.typeIcon : city"
+                :src="subItem?.typeIcon"
                 alt=""
               />
             </div>
@@ -459,6 +460,7 @@
 </template>
 <script setup>
 import city from '~/assets/img/chat/city-one.svg'
+import book from '~/assets/img/chat/book.svg'
 
 const route = useRoute()
 

+ 42 - 23
src/pages/chat/single-add.vue

@@ -104,6 +104,7 @@
         </div>
       </div>
       <van-button
+        :loading="isLoading"
         :disabled="checkedList.length > 0 ? false : true"
         @click="handleCreateGroup"
         style="width: 160px"
@@ -120,8 +121,6 @@
   </div>
 </template>
 <script setup>
-import { pinyin } from 'pinyin-pro'
-
 const route = useRoute()
 
 definePageMeta({
@@ -131,7 +130,8 @@ definePageMeta({
 onMounted(() => {
   getList()
 })
-
+// 对方的那个id
+const toUserId = computed(() => route.query.toUserId ?? '')
 const refreshing = ref(false)
 const loading = ref(false)
 const finished = ref(false)
@@ -222,30 +222,49 @@ const getList = async () => {
   }
 }
 
+// 节流
+const isLoading = ref(false)
+
+function handleKeyDown(event) {
+  // 启动节流
+  // 1000ms 后解除节流
+  // setTimeout(() => {
+  //   isThrottled.value = false
+  // }, 3000)
+}
+
 // 创建多人聊天
 async function handleCreateGroup() {
-  try {
-    showLoadingToast({
-      message: '准备开始群聊...',
-      duration: 100000
-    })
-    let { data } = request('/website/tourGroup/createGroup', {
-      method: 'post',
-      body: {
-        createType: 2,
-        ids: checked.value
-      }
-    })
-    if (data) {
-      navigateTo({
-        path: '/chat/group-chat',
-        query: data,
-        replace: true
+  if (!isLoading.value) {
+    isLoading.value = true
+    try {
+      showLoadingToast({
+        message: '准备开始群聊...',
+        duration: 100000
+      })
+
+      let { data } = await request('/website/tourGroup/createGroup', {
+        method: 'post',
+        body: {
+          createType: 2,
+          ids: [...checked.value, toUserId.value]
+        }
       })
+
+      if (data) {
+        navigateTo({
+          path: '/chat/group-chat',
+          query: {
+            groupId: data
+          },
+          replace: true
+        })
+        isLoading.value = false
+      }
+    } catch (error) {
+    } finally {
+      closeToast()
     }
-  } catch (error) {
-  } finally {
-    closeToast()
   }
 }
 

+ 75 - 84
src/pages/chat/single-chat.vue

@@ -3,7 +3,7 @@
     <van-nav-bar @click-left="router.back()" @click-right="onClickRight">
       <template #left>
         <div>
-          <van-icon name="arrow-left" color="black" size="18"/>
+          <van-icon name="arrow-left" color="black" size="18" />
         </div>
       </template>
       <template #title>
@@ -15,29 +15,32 @@
         </div>
       </template>
       <template #right>
-        <van-icon name="ellipsis" color="black" size="18"/>
+        <van-icon name="ellipsis" color="black" size="18" />
       </template>
     </van-nav-bar>
     <template v-if="showPage">
-
-      <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>
+      <!-- <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>
+        <ChatInput
+          :operates="['image']"
+          @focus="scrollToBottom"
+          @send="handleSendMessage"
+        ></ChatInput>
       </div>
     </template>
     <template v-else>
@@ -56,49 +59,48 @@
 </template>
 <script setup>
 import ChatMessage from './components/chat-message'
-import ChatInput from "./components/chat-input";
-import {findHyperlinks} from "~/pages/chat/components/chat-message/link-message/handle";
-import {XYWebSocket} from "~/utils/XYWebSocket";
+import ChatInput from './components/chat-input'
+import { findHyperlinks } from '~/pages/chat/components/chat-message/link-message/handle'
+import { XYWebSocket } from '~/utils/XYWebSocket'
 
 const route = useRoute()
 const router = useRouter()
 
-const chatsStore = useChatsStore();
-const userInfoStore = useUserInfoStore();
+const chatsStore = useChatsStore()
+const userInfoStore = useUserInfoStore()
 
-const {userInfo} = storeToRefs(userInfoStore);
+const { userInfo } = storeToRefs(userInfoStore)
 // 单聊的标题
-const title = computed(() => route.query.groupRemark)
+const title = computed(() => route.query?.groupRemark)
 
 // 聊天列表
-const chatListRef = ref(null);
+const chatListRef = ref(null)
 
 const followStatus = ref(0)
 
-const pageLoading = ref(true);
-const getUserId = ref(route.query?.getUserId); // 消息接收者的用户id
+const pageLoading = ref(true)
+const getUserId = ref(route.query?.getUserId) // 消息接收者的用户id
 const sendUserId = computed(() => userInfo?.value.pass) // 消息发送者:当前登录用户的加密id
-const groupId = ref(null); // 会话ID
+const groupId = ref(null) // 会话ID
 const showPage = computed(() => getUserId.value && groupId.value)
 
 const initGroupId = async () => {
   try {
-    if (!getUserId.value) return;
-    pageLoading.value = true;
+    if (!getUserId.value) return
+    pageLoading.value = true
     const res = await chatsStore.getCurrConversationId(getUserId.value)
     await handleResponse(res)
-    groupId.value = res.data;
+    groupId.value = res.data
     await getChatList('init')
   } catch (e) {
-
   } finally {
-    pageLoading.value = false;
+    pageLoading.value = false
   }
 }
 
-let pageNum = ref(0);
+let pageNum = ref(0)
 let totalCount = ref(0)
-const currConversationChatList = ref([]);
+const currConversationChatList = ref([])
 /**
  * 加载当前聊天信息
  * @param type init|more
@@ -107,7 +109,7 @@ const currConversationChatList = ref([]);
 const getChatList = async (type = 'init') => {
   try {
     let lastMessageId = null
-    let page = 1;
+    let page = 1
     if (type === 'more') {
       lastMessageId = getLastMessageId()
       page = pageNum.value + 1
@@ -118,13 +120,14 @@ const getChatList = async (type = 'init') => {
       groupId: groupId.value,
       messageId: type === 'more' ? lastMessageId : null
     })
-    pageNum.value = page;
-    await handleResponse(res);
-    let resList = chatsStore.handleMessageList(res.data?.data);
-    totalCount.value = res.data.count;
+    pageNum.value = page
+    await handleResponse(res)
+    let resList = chatsStore.handleMessageList(res.data?.data)
+    totalCount.value = res.data.count
 
-    if (type === 'more') {// 滚动条位置
-      resList = resList.filter(o => o.messageId !== lastMessageId);
+    if (type === 'more') {
+      // 滚动条位置
+      resList = resList.filter((o) => o.messageId !== lastMessageId)
       currConversationChatList.value = [...resList, ...currConversationChatList.value]
     } else {
       currConversationChatList.value = resList
@@ -134,12 +137,11 @@ const getChatList = async (type = 'init') => {
   } catch (e) {
     console.error(e)
   } finally {
-
   }
 }
 
 const getLastMessageId = () => {
-  const len = currConversationChatList.value.length;
+  const len = currConversationChatList.value.length
   if (len) {
     return currConversationChatList.value[0]?.messageId ?? null
   }
@@ -166,14 +168,13 @@ const sendTextMessage = async (text) => {
       }
     }
     const isLink = !!findHyperlinks(text)
-    if (isLink) msg.messageType = 4;
+    if (isLink) msg.messageType = 4
     currConversationChatList.value.push(msg)
     await scrollToBottom()
     await chatsStore.sendSocketMessage(msg)
   } catch (e) {
     console.log(e, '2')
   } finally {
-
   }
 }
 
@@ -184,7 +185,7 @@ const sendImageMessage = async (file) => {
     formData.append('uploadFile', file)
     formData.append('asImage', true)
     formData.append('fieldName', 'messageContent')
-    const {data} = await request('/website/tourMessage/upload', {
+    const { data } = await request('/website/tourMessage/upload', {
       method: 'post',
       body: formData
     })
@@ -210,29 +211,24 @@ const sendImageMessage = async (file) => {
   } catch (e) {
     console.error(e, '??')
   } finally {
-
   }
 }
 
-const handleSendMessage = async ({type, messageContent}) => {
+const handleSendMessage = async ({ type, messageContent }) => {
   try {
     switch (type) {
       case 'text':
         await sendTextMessage(messageContent)
-        break;
+        break
       case 'image':
         await sendImageMessage(messageContent)
-        break;
+        break
 
       default:
-
-        break;
+        break
     }
-
   } catch (e) {
-
   } finally {
-
   }
 }
 
@@ -240,32 +236,31 @@ const scrollToBottom = async () => {
   // 操作向上加载不滚动 TODO 判断用户是否有向上滑的操作更准确
   if (refreshing.value) return
   setTimeout(async () => {
-    await nextTick(); // 确保DOM已经更新
-    const listElement = chatListRef.value?.$el;
+    await nextTick() // 确保DOM已经更新
+    const listElement = chatListRef.value?.$el
     if (listElement) {
-      const scrollContainer = listElement;
-      scrollContainer.scrollTop = scrollContainer.scrollHeight;
+      const scrollContainer = listElement
+      scrollContainer.scrollTop = scrollContainer.scrollHeight
     }
   }, 200)
-};
+}
 
 // 获取我与对方的关注情况
 const getFollowStatus = async () => {
   const query = {
     userId: getUserId.value
   }
-  const {data: status = 0} = await request('/website/tourGroup/isFollow', {query})
+  const { data: status = 0 } = await request('/website/tourGroup/isFollow', { query })
   followStatus.value = status
 }
 
-
 // 加载更多
 const refreshing = ref(false)
 const loadMore = async () => {
   try {
     refreshing.value = true
     if (currConversationChatList.value.length) {
-      if(totalCount.value === currConversationChatList.value.length) {
+      if (totalCount.value === currConversationChatList.value.length) {
         // 已经加载了全部
       } else {
         await getChatList('more')
@@ -283,12 +278,12 @@ const onClickRight = () => {
   navigateTo({
     path: '/chat/set-single',
     query: {
-      toUserId: route.query.getUserId
+      toUserId: route.query.getUserId,
+      groupId: groupId.value
     }
   })
 }
 
-
 // 本地生成一个唯一消息id
 function getLocalId() {
   const random = Math.floor(Math.random() * 10000)
@@ -299,7 +294,7 @@ onMounted(() => {
   initGroupId()
   XYWebSocket.SocketEventsBus.on('chat-event', async (chat) => {
     console.log('单聊页面消息订阅', chat)
-    const isCurrGroupId = chat.groupId && chat.groupId === groupId.value;
+    const isCurrGroupId = chat.groupId && chat.groupId === groupId.value
     const isOtherUserMessage = chat.sendUserId && chatsStore.isRealMessage(chat.sendUserId)
     if (isCurrGroupId) {
       if (isOtherUserMessage) {
@@ -310,13 +305,10 @@ onMounted(() => {
         await getChatList('init')
       }
     }
-
   })
 })
 
-watchEffect(() => {
-
-})
+watchEffect(() => {})
 
 // 用户删除消息
 const delMessage = (messageId) => {
@@ -325,19 +317,18 @@ const delMessage = (messageId) => {
     message: '是否删除这条消息?',
     confirmButtonColor: '#FF9300'
   })
-      .then(async () => {
-        const res = await request('/website/tourMessage/delMessage', {
-          method: 'post',
-          body: {
-            messageId: [messageId]
-          }
-        })
-
-        if (res && res?.success) {
+    .then(async () => {
+      const res = await request('/website/tourMessage/delMessage', {
+        method: 'post',
+        body: {
+          messageId: [messageId]
         }
       })
-      .catch(() => {
-      })
+
+      if (res && res?.success) {
+      }
+    })
+    .catch(() => {})
 }
 
 definePageMeta({

+ 8 - 11
src/pages/chat/user-add.vue

@@ -3,9 +3,12 @@
     <ChatHeaderBar title="添加用户" />
 
     <ChatSearch v-model:searchString="showName" @search="search" placeholder="请输入关键词" />
-
     <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
-      <div style="height: calc(100vh - 150px)" class="w-full min-h-500">
+      <!-- <div style="height: 100vh" class="border overflow-y-auto"> -->
+      <div
+        style="height: calc(100vh - 100px)"
+        class="w-full min-h-500 overflow-y-auto mb-10 box-border"
+      >
         <ChatEmpty
           v-if="!list?.length && !loading"
           image="search"
@@ -143,10 +146,10 @@ useSeoMeta({
 })
 
 const search = () => {
+  list.value = []
   queryParams.pageNum = 1
   queryParams.showName = showName.value
   finished.value = false
-  list.value = []
   getList()
 }
 
@@ -197,8 +200,6 @@ const getList = async () => {
       }
     })
 
-    console.log(dataList.length, '  length')
-
     if (Array.isArray(dataList) && dataList?.length) {
       list.value = list.value.concat(dataList)
     } else {
@@ -208,11 +209,8 @@ const getList = async () => {
     loading.value = false
     refreshing.value = false
     if (list.value.length >= totalCount) {
-      console.log('111')
-
       finished.value = true
     } else {
-      console.log('2222')
       finished.value = false
     }
   } catch (err) {
@@ -231,7 +229,6 @@ function getLocalId() {
 // 创建单聊的会话
 const createSingle = async (body) => {
   body.groupId = getLocalId()
-  console.log(userInfo.value, 'userInfo.value')
 
   body.sendUserId = userInfo.value.userId
   const { data } = await request('/website/tourGroup/createMember', {
@@ -239,8 +236,8 @@ const createSingle = async (body) => {
     body
   })
   if (data) {
-    navigateTo('/chat/single', {
-      groupId: data,
+    navigateTo({
+      path: '/profile/my-news',
       replace: true
     })
   }

+ 73 - 48
src/pages/follow/components/follow-list/index.vue

@@ -1,15 +1,15 @@
 <template>
   <van-list
-      v-if="total"
-      class="follow-list"
-      v-model:loading="loading"
-      :finished="isFinished"
-      finished-text="-- 没有更多了 --"
-      @load="onLoad"
+    v-if="total"
+    class="follow-list"
+    v-model:loading="loading"
+    :finished="isFinished"
+    finished-text="-- 没有更多了 --"
+    @load="onLoad"
   >
     <van-cell v-for="(item, i) in list" :key="i">
       <div class="follow-item flex flex-row items-center w-full h-82 text-left" fit="cover">
-        <van-image width="48" height="48" round class="mr-12" :src="item.avatar"/>
+        <van-image width="48" height="48" round class="mr-12" :src="item?.avatar" />
         <div class="flex-col flex-1 mr-12 min-w-0">
           <div class="text-xl text-black-3 font-bold text-ellipsis text-nowrap overflow-hidden ...">
             {{ item.nickName }}
@@ -18,19 +18,26 @@
             粉丝量:{{ item.fansNumText }}
           </div>
         </div>
-       <div class="items-end w-92 flex justify-end">
-         <van-button class="follow-item__button" plain :disabled="item.saveLoading" :color="FANS_STATUS[item.fansStatus].bg" type="primary" @click="handleFollow(item)">
-           {{ FANS_STATUS[item.fansStatus].text }}
-         </van-button>
-       </div>
+        <div class="items-end w-92 flex justify-end">
+          <van-button
+            class="follow-item__button"
+            plain
+            :disabled="item.saveLoading"
+            :color="FANS_STATUS[item.fansStatus].bg"
+            type="primary"
+            @click="handleFollow(item)"
+          >
+            {{ FANS_STATUS[item.fansStatus].text }}
+          </van-button>
+        </div>
       </div>
     </van-cell>
   </van-list>
-  <van-empty v-else :description="currListConfig.empty"/>
+  <van-empty v-else :description="currListConfig.empty" />
 </template>
 <script setup>
 const props = defineProps({
-  listType: {type: String, default: 'friend'}, // friend|follow|fans
+  listType: { type: String, default: 'friend' } // friend|follow|fans
 })
 
 const listConfig = new Map([
@@ -38,21 +45,21 @@ const listConfig = new Map([
     'friend',
     {
       empty: '暂无互关',
-      apiUrl: '/website/tourism/fans/getFriends',
+      apiUrl: '/website/tourism/fans/getFriends'
     }
   ],
   [
     'follow',
     {
       empty: '暂无关注',
-      apiUrl: '/website/tourism/fans/getMyConCern',
+      apiUrl: '/website/tourism/fans/getMyConCern'
     }
   ],
   [
     'fans',
     {
       empty: '暂无粉丝',
-      apiUrl: '/website/tourism/fans/getMyFans',
+      apiUrl: '/website/tourism/fans/getMyFans'
     }
   ]
 ])
@@ -67,62 +74,80 @@ const currListConfig = computed(() => {
   return listConfig.get(props.listType) ?? listConfig.get('friend')
 })
 
-let loading = ref(false);
-let isFinished = ref(false);
-let pageNum = ref(0);
-let list = ref([]);
-let total = ref(0);
+let loading = ref(false)
+let isFinished = ref(false)
+let pageNum = ref(0)
+let list = ref([])
+let total = ref(0)
 
 const onLoad = async () => {
   try {
-    if (loading.value || isFinished.value) return;
+    if (loading.value || isFinished.value) return
     loading.value = true
-    pageNum.value += 1;
+    pageNum.value += 1
 
     const res = await request(`${currListConfig.value.apiUrl}`, {
       query: {
-        pageNum: pageNum.value,
-      },
-    });
+        pageNum: pageNum.value
+      }
+    })
     await handleResponse(res)
-    const {dataList, totalCount} = res.data
-    // console.log(dataList, totalCount, 'total==??', props.listType)
-    const _list = dataList.map((o) => ({
-      ...o,
-      avatar: o.attentionIdDictMap.avatar,
-      nickName: o.attentionIdDictMap?.name ?? '',
-      fansNumText: formatNumber(o.fansNum || 0),
-      saveLoading: false
-    }))
+    const { dataList, totalCount } = res.data
+    let _list = []
+    if (props.listType == 'fans') {
+      _list = dataList.map((o) => ({
+        ...o,
+        avatar: o.createUserIdDictMap?.avatar,
+        nickName: o.createUserIdDictMap?.name ?? '',
+        fansNumText: formatNumber(o.fansNum || 0),
+        attentionId: o.createUserIdDictMap?.id,
+        saveLoading: false
+      }))
+    } else if (props.listType == 'friend') {
+      _list = dataList.map((o) => ({
+        ...o,
+        avatar: o.attentionIdDictMap?.headImageUrl,
+        nickName: o.attentionIdDictMap?.showName ?? '',
+        fansNumText: formatNumber(o.fansNum || 0),
+        saveLoading: false
+      }))
+    } else {
+      _list = dataList.map((o) => ({
+        ...o,
+        avatar: o.attentionIdDictMap.avatar,
+        nickName: o.attentionIdDictMap?.name ?? '',
+        fansNumText: formatNumber(o.fansNum || 0),
+        saveLoading: false
+      }))
+    }
 
-    list.value.push(..._list);
-    total.value = totalCount;
-    isFinished.value = list.value.length >= total.value;
+    list.value.push(..._list)
+    total.value = totalCount
+    isFinished.value = list.value.length >= total.value
   } catch (e) {
-
   } finally {
     loading.value = false
   }
 }
 const handleFollow = async (item) => {
   let currIndex = list.value.findIndex((o) => o.id === item.id)
-  if(currIndex < 0) return
+  if (currIndex < 0) return
   try {
     if (list.value[currIndex].saveLoading) return
-    list.value[currIndex].saveLoading = true;
-    const {data} = await request(`/website/tourism/fans/saveConcern`, {
+    list.value[currIndex].saveLoading = true
+    const { data } = await request(`/website/tourism/fans/saveConcern`, {
       method: 'post',
       body: {
         attentionId: item.attentionId
       }
-    });
-    if(!data) return
-    list.value[currIndex].fansStatus = data.fansStatus;
+    })
+    if (!data) return
+    list.value[currIndex].fansStatus = data.fansStatus
     showSuccessToast('操作成功')
   } catch (e) {
     showToast('操作失败')
   } finally {
-    list.value[currIndex].saveLoading = false;
+    list.value[currIndex].saveLoading = false
   }
 }
 
@@ -139,4 +164,4 @@ onLoad()
     font-size: 14px;
   }
 }
-</style>
+</style>

+ 27 - 24
src/pages/follow/index.vue

@@ -1,41 +1,45 @@
 <template>
   <div class="follow-page">
-    <van-tabs v-model:active="currentTab"
-              border color="#FD9A00"
-              title-active-color="#FD9A00"
-              title-inactive-color="#333333">
-      <van-tab
-          v-for="(item, i) in tabList"
-          :key="i"
-          :title="item.label"
-          :name="item.listType"
-      >
-        <FollowList
-            :list-type="item.listType"
-        ></FollowList>
+    <van-tabs
+      v-model:active="currentTab"
+      border
+      color="#FD9A00"
+      title-active-color="#FD9A00"
+      title-inactive-color="#333333"
+    >
+      <van-tab v-for="(item, i) in tabList" :key="i" :title="item.label" :name="item.listType">
+        <FollowList :list-type="item.listType"></FollowList>
       </van-tab>
     </van-tabs>
   </div>
+  <!--   @click-tab="onClickTab" -->
 </template>
+
 <script setup>
-import FollowList from './components/follow-list';
+import FollowList from './components/follow-list'
 const route = useRoute()
 
-const currentTab = ref(route?.query?.listType ?? 'friend');
+const currentTab = ref(route?.query?.listType ?? 'friend')
 const tabList = ref([
   {
-    label: "互关",
-    listType: 'friend',
+    label: '互关',
+    listType: 'friend'
   },
   {
-    label: "关注",
-    listType: 'follow',
+    label: '关注',
+    listType: 'follow'
   },
   {
-    label: "粉丝",
-    listType: 'fans',
+    label: '粉丝',
+    listType: 'fans'
   }
-]);
+])
+
+// function onClickTab({ title }) {
+//   console.log(title, '-----onClickTab----')
+
+//   currentTab.value = tabList.value.find((item) => item.label == title).listType
+// }
 </script>
 <style scoped lang="scss">
 :deep(.van-tabs) {
@@ -55,5 +59,4 @@ const tabList = ref([
 .follow-page {
   height: calc(100vh - 52px);
 }
-
-</style>
+</style>

+ 57 - 56
src/pages/profile/interaction-message/index.vue

@@ -35,62 +35,63 @@
           image="conment"
           :title="`暂无${interactionTitle}`"
         />
-        <van-list
-          v-if="interactionList.length"
-          v-model:loading="loading"
-          :finished="finished"
-          :immediate-check="false"
-          finished-text=""
-          @load="handleCurrentChange"
-        >
-          <template v-for="item in interactionList" :key="item?.id">
-            <!-- 点赞与收藏 -->
-            <ProfileInteractionMessageLikesandFavorites
-              v-if="item.noticeType == 5 || item.noticeType == 7"
-              :item-data="{
-                ...item,
-                messageContent:
-                  actionTypeList[item.noticeType].text + businessTypeList[item.businessType].text
-              }"
-            ></ProfileInteractionMessageLikesandFavorites>
-
-            <!-- 艾特  -->
-            <ProfileInteractionMessageEit
-              v-if="item.noticeType == 10"
-              :item-data="{
-                ...item,
-                messageContent:
-                  actionTypeList[item.noticeType].text + businessTypeList[item.businessType].text
-              }"
-            ></ProfileInteractionMessageEit>
-
-            <!-- 收到的评论 是评论还是 回复 -->
-            <ProfileInteractionMessageReceiveComment
-              v-if="
-                (item.noticeType == 6 && interactionIndex == 7) ||
-                (item.noticeType == 12 && interactionIndex == 7)
-              "
-              :item-data="{
-                ...item,
-                messageContent: messageContentParse(item?.messageContent)
-              }"
-              :user-info="userInfo"
-              @on-add-reply="addReply(item, item.reviewId)"
-            />
-
-            <!-- 发出的评论 -->
-            <ProfileInteractionMessageSendComment
-              v-if="
-                (item.noticeType == 6 && interactionIndex == 8) ||
-                (item.noticeType == 12 && interactionIndex == 8)
-              "
-              :item-data="{
-                ...item,
-                messageContent: messageContentParse(item?.messageContent)
-              }"
-            />
-          </template>
-        </van-list>
+        <div v-if="interactionList.length">
+          <van-list
+            v-model:loading="loading"
+            :finished="finished"
+            :immediate-check="false"
+            finished-text=""
+            @load="handleCurrentChange"
+          >
+            <template v-for="item in interactionList" :key="item?.id">
+              <!-- 点赞与收藏 -->
+              <ProfileInteractionMessageLikesandFavorites
+                v-if="item.noticeType == 5 || item.noticeType == 7"
+                :item-data="{
+                  ...item,
+                  messageContent:
+                    actionTypeList[item.noticeType].text + businessTypeList[item.businessType].text
+                }"
+              ></ProfileInteractionMessageLikesandFavorites>
+
+              <!-- 艾特  -->
+              <ProfileInteractionMessageEit
+                v-if="item.noticeType == 10"
+                :item-data="{
+                  ...item,
+                  messageContent:
+                    actionTypeList[item.noticeType].text + businessTypeList[item.businessType].text
+                }"
+              ></ProfileInteractionMessageEit>
+
+              <!-- 收到的评论 是评论还是 回复 -->
+              <ProfileInteractionMessageReceiveComment
+                v-if="
+                  (item.noticeType == 6 && interactionIndex == 7) ||
+                  (item.noticeType == 12 && interactionIndex == 7)
+                "
+                :item-data="{
+                  ...item,
+                  messageContent: messageContentParse(item?.messageContent)
+                }"
+                :user-info="userInfo"
+                @on-add-reply="addReply(item, item.reviewId)"
+              />
+
+              <!-- 发出的评论 -->
+              <ProfileInteractionMessageSendComment
+                v-if="
+                  (item.noticeType == 6 && interactionIndex == 8) ||
+                  (item.noticeType == 12 && interactionIndex == 8)
+                "
+                :item-data="{
+                  ...item,
+                  messageContent: messageContentParse(item?.messageContent)
+                }"
+              />
+            </template>
+          </van-list>
+        </div>
 
         <!-- <div
           v-if="showInput"

+ 0 - 483
src/pages/profile/my-news/_index.vue

@@ -1,483 +0,0 @@
-<template>
-  <div class="w-full">
-    <!--    <audio
-      class="fixed top-0 left-0"
-      ref="audioRef"
-      :src="audioTips"
-      style="opacity: 0; z-index: -1"
-    ></audio>-->
-
-    <!-- <van-pull-refresh v-model="refreshing" @refresh="onRefresh"> -->
-    <van-sticky :offset-top="50">
-      <div class="w-full text-xl font-semibold px-16 h-48 flex justify-start items-center bg-white">
-        <span
-          @click="showPopover = true"
-          v-if="showPopover"
-          class="iconfont icon-plus text-[#FF9300]"
-          style="font-size: 24px"
-        ></span>
-        <span v-else class="iconfont icon-plus text-black" style="font-size: 24px"></span>
-
-        <van-popover
-          v-model:show="showPopover"
-          placement="bottom"
-          theme="dark"
-          offset="[5,20]"
-          :actions="actionsList"
-          @select="onSelect"
-        >
-          <template #reference>
-            <span :class="`${showPopover ? 'text-[#FF9300]' : 'text-black-3'}`">添加</span>
-          </template>
-        </van-popover>
-      </div>
-    </van-sticky>
-
-    <div
-      @click="onChatPage('/profile/system-message', {})"
-      class="w-full relative h-82 flex justify-start items-center px-16"
-    >
-      <van-badge
-        v-if="chatList[0]?.unreadMessageCount"
-        v-bind="messageNumber(chatList[0]?.unreadMessageCount)"
-        max="99"
-      >
-        <div
-          class="w-48 h-48 bg-[#0052D9] rounded-full overflow-hidden flex justify-center items-center"
-        >
-          <img class="w-24 h-24 shrink-0 object-cover" src="~/assets/img/chat/remind.svg" alt="" />
-        </div>
-      </van-badge>
-
-      <div
-        v-else
-        class="w-48 h-48 bg-[#0052D9] rounded-full overflow-hidden flex justify-center items-center"
-      >
-        <img class="w-24 h-24 shrink-0 object-cover" src="~/assets/img/chat/remind.svg" alt="" />
-      </div>
-
-      <div class="h-48 w-245 shrink-0 ml-12 flex flex-wrap items-start">
-        <h1 class="line-clamp-1 w-full text-base text-black-3 font-semibold mb-4">
-          {{ chatList[0]?.groupName }}
-        </h1>
-        <p class="line-clamp-1 h-20 text-sm text-black-6 leading-3xl">
-          {{
-            chatList[0]?.lastMessage
-              ? messageContentParse(chatList[0]?.lastMessage?.messageContent)
-              : ''
-          }}
-        </p>
-      </div>
-
-      <div class="w-35 h-48 shrink-0">
-        <p class="text-black/[0.6] text-sm text-end">
-          {{
-            chatList[0]?.lastMessage ? createTimeSplit(chatList[0]?.lastMessage?.createTime) : ''
-          }}
-        </p>
-      </div>
-      <div class="absolute bottom-0 right-0 w-[96%] h-1 border-b-[1px]"></div>
-    </div>
-
-    <div
-      @click="navigateTo('/follow?listType=fans')"
-      class="w-full relative h-82 flex justify-start items-center px-16"
-    >
-      <van-badge
-        v-if="chatList[1]?.unreadMessageCount"
-        v-bind="messageNumber(chatList[1]?.unreadMessageCount)"
-        max="99"
-      >
-        <div
-          class="w-48 h-48 bg-[#FF9300] rounded-full overflow-hidden flex justify-center items-center"
-        >
-          <img class="w-24 h-24 shrink-0 object-cover" src="~/assets/img/chat/user.svg" alt="" />
-        </div>
-      </van-badge>
-
-      <div
-        v-else
-        @click="navigateTo('/follow?listType=fans')"
-        class="w-48 h-48 bg-[#0052D9] rounded-full overflow-hidden flex justify-center items-center"
-      >
-        <img class="w-24 h-24 shrink-0 object-cover" src="~/assets/img/chat/user.svg" alt="" />
-      </div>
-
-      <div class="h-48 w-245 shrink-0 ml-12 flex flex-wrap items-start">
-        <h1 class="line-clamp-1 w-full text-base text-black-3 font-semibold mb-4">
-          {{ chatList[1]?.groupName }}
-        </h1>
-        <p class="line-clamp-1 h-20 text-sm text-black-6 leading-3xl">
-          {{
-            chatList[1]?.lastMessage
-              ? messageContentParse(chatList[1]?.lastMessage?.messageContent)
-              : ''
-          }}
-        </p>
-      </div>
-
-      <div class="w-35 h-48 shrink-0">
-        <p class="text-black/[0.6] text-sm text-end">
-          {{
-            chatList[1]?.lastMessage ? createTimeSplit(chatList[1]?.lastMessage?.createTime) : ''
-          }}
-        </p>
-      </div>
-      <div class="absolute bottom-0 right-0 w-[96%] h-1 border-b-[1px]"></div>
-    </div>
-    <div
-      @click="onChatPage('/profile/interaction-message', {})"
-      class="w-full relative h-82 flex justify-start items-center px-16"
-    >
-      <van-badge v-if="messagesNumber > 0" v-bind="messageNumber(messagesNumber)" max="99">
-        <div
-          class="w-48 h-48 bg-[#FF476A] rounded-full overflow-hidden flex justify-center items-center"
-        >
-          <img
-            class="w-24 h-24 shrink-0 object-cover"
-            src="~/assets/img/chat/weixin-shake.svg"
-            alt=""
-          />
-        </div>
-      </van-badge>
-
-      <div
-        v-else
-        class="w-48 h-48 bg-[#FF476A] rounded-full overflow-hidden flex justify-center items-center"
-      >
-        <img
-          class="w-24 h-24 shrink-0 object-cover"
-          src="~/assets/img/chat/weixin-shake.svg"
-          alt=""
-        />
-      </div>
-
-      <div class="h-48 w-245 shrink-0 ml-12 flex flex-wrap items-start">
-        <h1 class="line-clamp-1 w-full text-base text-black-3 font-semibold mb-4">
-          {{ chatList[2]?.groupName }}
-        </h1>
-        <p class="line-clamp-1 h-20 text-sm text-black-6 leading-3xl">
-          {{
-            chatList[2]?.lastMessage
-              ? messageContentParse(chatList[2]?.lastMessage?.messageContent)
-              : ''
-          }}
-        </p>
-      </div>
-
-      <div class="w-35 h-48 shrink-0">
-        <p class="text-black/[0.6] text-sm text-end">
-          {{
-            chatList[2]?.lastMessage ? createTimeSplit(chatList[2]?.lastMessage?.createTime) : ''
-          }}
-        </p>
-      </div>
-      <div class="absolute bottom-0 right-0 w-[96%] h-1 border-b-[1px]"></div>
-    </div>
-
-    <!-- 置顶绘画列表  "-->
-    <div v-if="isTopList?.length && activeNames" class="w-full">
-      <template v-for="(item, index) in isTopList" :key="item?.id">
-        <template v-if="index > 2">
-          <!-- 单聊会话 -->
-          <ProfileNewsGroupChat
-            v-if="item?.noticeType == 2"
-            :item-data="{
-              ...item,
-              updateTime: item?.lastMessage ? createTimeSplit(item?.lastMessage?.updateTime) : ''
-            }"
-            @on-chat-page="
-              onChatPage('/chat/group-chat', { userId: user.userId, groupId: item?.groupId })
-            "
-            @on-no-bother="noBother(item)"
-            @on-is-top="onIsTop(item)"
-            @on-conv-delete="onIsShow(item)"
-          />
-
-          <!-- 群聊会话 -->
-          <ProfileNewsSingleChat
-            v-if="item?.noticeType == 1"
-            :item-data="{
-              ...item,
-              updateTime: item?.lastMessage ? createTimeSplit(item?.lastMessage?.updateTime) : ''
-            }"
-            @on-chat-page="
-              onChatPage('/chat/single', {
-                sendUserId: userInfo.userId,
-                groupId: item?.groupId,
-                getUserId: item?.toUserId,
-                groupRemark: item?.groupRemark
-              })
-            "
-            @on-no-bother="noBother(item)"
-            @on-is-top="onIsTop(item)"
-            @on-conv-delete="onIsShow(item)"
-          />
-        </template>
-        <template v-else></template>
-      </template>
-    </div>
-
-    <div
-      v-if="isTopList.length >= 6"
-      @click="activeNames = !activeNames"
-      class="flex justify-between border items-center h-20 w-full p-16 box-border"
-    >
-      <div class="shrink-0 flex items-center">
-        <van-icon name="bars" size="16" class="mr-5" />
-        <span class="text-sm">{{ collapseTitle }}</span>
-      </div>
-      <div class="w-16 h-16 shrink-0">
-        <van-icon name="arrow" size="16" />
-      </div>
-    </div>
-
-    <!-- 不置顶的会话列表 -->
-    <template v-for="(item, index) in pinnedList" :key="item?.id">
-      <ProfileNewsGroupChat
-        v-if="item?.noticeType == 2"
-        :item-data="{
-          ...item,
-          updateTime: item?.lastMessage ? createTimeSplit(item?.lastMessage?.updateTime) : ''
-        }"
-        @on-chat-page="
-          onChatPage('/chat/group-chat', {
-            userId: userInfo.userId,
-            groupId: item?.groupId
-          })
-        "
-        @on-no-bother="noBother(item)"
-        @on-is-top="onIsTop(item)"
-        @on-conv-delete="onIsShow(item)"
-      />
-      <ProfileNewsSingleChat
-        v-if="item?.noticeType == 1"
-        :item-data="{
-          ...item,
-          updateTime: item?.lastMessage ? createTimeSplit(item?.lastMessage?.updateTime) : ''
-        }"
-        @on-chat-page="
-          onChatPage('/chat/single', {
-            sendUserId: userInfo.userId,
-            groupId: item?.groupId,
-            getUserId: item?.toUserId,
-            groupRemark: item?.groupRemark
-          })
-        "
-        @on-no-bother="noBother(item)"
-        @on-is-top="onIsTop(item)"
-        @on-conv-delete="onIsShow(item)"
-      />
-    </template>
-    <!-- </van-pull-refresh> -->
-  </div>
-</template>
-
-<script setup>
-import comments from '~/assets/img/chat/comments-white.svg'
-import plaza from '~/assets/img/chat/guangchang.svg'
-import userAdd from '~/assets/img/chat/user-add.svg'
-
-import { messageContentParse } from '~/utils/detalTime.js'
-
-const actionsList = [
-  { text: '创建群聊', icon: comments },
-  { text: '群聊广场', icon: plaza },
-  { text: '加入群聊', icon: plaza },
-  { text: '添加用户', icon: userAdd }
-]
-const userInfoStore = useUserInfoStore()
-const { userInfo } = storeToRefs(userInfoStore)
-// const uploadUrl = `${import.meta.env.VITE_APP_BASE_URL}/website/tourMessage/upload`
-const chatStore = useChatStore()
-const { messages, connectSta, chatList, curConversiton, onNewMessage } = storeToRefs(chatStore)
-
-// 链接的状态
-const wsConnect = computed(() => connectSta.value)
-
-const chatLists = computed(() => chatList.value)
-
-const audioRef = ref(null)
-
-const finished = ref(false)
-
-const error = ref(false)
-
-const loading = ref(false)
-
-const showPopover = ref(false)
-
-const messagesNumber = ref(10)
-
-// 置顶列表
-const isTopList = computed(() => chatList.value.filter((el) => el.isTop != 1))
-const pinnedList = computed(() => chatList.value.filter((el) => el?.isTop == 1) ?? [])
-const pinnedSystemList = ref([]) //三个固定的消息
-
-// 个置顶聊天
-const collapse_text = '折叠置顶聊天'
-
-const activeNames = ref(true)
-// collapse
-const collapseTitle = ref(collapse_text)
-
-// 刷新
-const refreshing = ref(false)
-
-// 建立链接
-// async function getUserInfo() {
-//   const { data } = await request('/website/tourism/user/view')
-//   chatStore.user = data
-//   user.value = data
-//   console.log(data, 'createConnection')
-
-//   await chatStore.createConnection(data.pass)
-//   chatStore.reqChatList()
-
-//   console.log('用户信息:', chatStore.user)
-
-//   // console.log('会话列表:', chatStore.chatList.value)
-// }
-
-useSeoMeta({
-  title: '我的消息'
-})
-
-// 时间的转换
-const createTimeSplit = (timer) => {
-  if (timer) {
-    return timer.split(' ')[1]
-  }
-}
-// 下拉刷新
-const onRefresh = () => {
-  refreshing.value = true
-  chatStore.reqChatList()
-  refreshing.value = false
-}
-
-// 打扰和免打扰得
-const noBother = (parmas) => {
-  handleBoolean({ groupId: parmas.groupId, isNotDisturb: parmas.isNotDisturb })
-}
-
-// 是否置顶
-const onIsTop = (parmas) => {
-  handleBoolean({ groupId: parmas.groupId, isTop: parmas.isTop })
-}
-
-// 是否显示会话
-const onIsShow = (parmas) => {
-  handleBoolean({ groupId: parmas.groupId, isShow: parmas.isShow })
-}
-
-// 是否免打扰和 是否置顶 公共
-const handleBoolean = async (body) => {
-  try {
-    let { data } = await request('/website/tourMember/updateSingleTourMember', {
-      method: 'post',
-      body
-    })
-    if (data) {
-      chatStore.reqChatList()
-    }
-  } catch (error) {}
-}
-
-// 消息数量通知的展示  需要动态的展示
-const messageNumber = (content) => {
-  let messageNumberObj = {}
-
-  if (content != null || content != undefined || content != '') {
-    if (content <= 1) {
-      messageNumberObj = {
-        offset: [-5, 4],
-        dot: true,
-        content
-      }
-    }
-    if (content > 1) {
-      messageNumberObj = {
-        offset: [-10, 7],
-        content
-      }
-    }
-  } else {
-    content = 0
-    messageNumberObj = {
-      offset: [-5, 4],
-      dot: true,
-      content
-    }
-  }
-
-  return messageNumberObj
-}
-
-// 跳转聊天页面
-const onChatPage = async (path, query) => {
-  const res = await request('/website/tourMessage/updateRead', {
-    query: {
-      groupId: query.groupId
-    }
-  })
-
-  if (res && res?.success) {
-    navigateTo({
-      path,
-      query
-    })
-  }
-}
-
-// 选中的是那个页面
-const onSelect = (action) => {
-  if (action.text == '创建群聊') onChatPage('/chat/create-group', {})
-  if (action.text == '群聊广场') onChatPage('/chat/group-square', {})
-  if (action.text == '加入群聊') onChatPage('/scan', {})
-  if (action.text == '添加用户') onChatPage('/chat/user-add', {})
-}
-
-onMounted(() => {
-  if (wsConnect == 0) {
-    showToast('聊天网络连接中...')
-  } else if (wsConnect == 1) {
-    showToast(' 聊天正在连接中...')
-  } else if (wsConnect == 3) {
-    showToast(' 聊天连接已断开,请刷新页面重新连接,或稍后重试!')
-  } else if (wsConnect == 2) {
-  }
-  chatStore.reqChatList()
-  // chatStore.reqChatList()
-})
-
-// watch(
-//   wsConnect,
-//   async (newValue, oldValue) => {
-//     console.log(newValue, 'wsConnect')
-//     console.log(chatLists.value, 'chatLists')
-
-//     if (newValue == 2) {
-//       pinnedList.value = chatList.value.filter((el) => el.isTop != 1)
-//       isTopList.value = chatList.value.filter((el) => el.isTop == 1)
-//     }
-//   },
-//   { immediate: true }
-// )
-// watch(
-//   chatList.value,
-//   (newList, oldList) => {
-//     // pinnedSystemList.value = newList.filter((el) => el.noticeType == 3)
-//     pinnedList.value = newList.filter((el) => el.isTop != 1)
-//     isTopList.value = newList.filter((el) => el.isTop == 1)
-
-//     console.log(pinnedList.value, 'pinnedList')
-//     console.log(isTopList.value, 'isTopList')
-//     // console.log(newList, 'newList')
-//     console.log(oldList, 'oldList')
-//   },
-//   { immediate: true }
-// )
-</script>
-
-<style lang="scss" scoped></style>

+ 14 - 36
src/pages/profile/my-news/index.vue

@@ -1,6 +1,6 @@
 <template>
-  <div class="w-full">
-    <van-sticky :offset-top="50">
+  <div class="w-full h-[100vh]">
+    <van-sticky :offset-top="48">
       <div class="w-full text-xl font-semibold px-16 h-48 flex justify-start items-center bg-white">
         <span
           @click="showPopover = true"
@@ -12,9 +12,9 @@
 
         <van-popover
           v-model:show="showPopover"
-          placement="bottom"
           theme="dark"
-          :offset="[5, 20]"
+          placement="bottom-start"
+          :offset="[-25, 5]"
           :actions="actionsList"
           @select="onSelect"
         >
@@ -24,15 +24,10 @@
         </van-popover>
       </div>
     </van-sticky>
+
     <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
-      <!--      class="h-full overflow-y-auto px-12 flex flex-col"-->
-      <div style="height: calc(100vh - 100px)" class="w-full h-full overflow-y-auto">
-        <van-list
-          ref="messageBoxRef"
-          class="flex-1 overflow-y-auto overflow-hidden flex flex-col"
-          :finished="true"
-          finished-text=""
-        >
+      <div class="h-[100vh] overflow-y-auto">
+        <van-list class="h-full" :finished="true" finished-text="">
           <div
             @click="
               onChatPage('/profile/system-message', {
@@ -73,11 +68,6 @@
                 {{ chatList[0]?.groupName }}
               </h1>
               <p class="line-clamp-1 h-20 text-sm text-black-6 leading-3xl">
-                <!-- {{
-                  chatList[0]?.lastMessage
-                    ? messageContentParse(chatList[0]?.lastMessage?.messageContent)
-                    : '暂无系统消息'
-                }} -->
                 {{
                   chatList[0]?.lastMessage
                     ? chatList[0]?.lastMessage?.messageContent?.messageContent
@@ -140,12 +130,6 @@
                 {{ chatList[1]?.groupName }}
               </h1>
               <p class="line-clamp-1 h-20 text-sm text-black-6 leading-3xl">
-                <!-- {{
-                  chatList[1]?.lastMessage
-                    ? messageContentParse(chatList[1]?.lastMessage?.messageContent)
-                    : '暂无新增关注消息'
-                }} -->
-
                 {{
                   chatList[1]?.lastMessage
                     ? chatList[1]?.lastMessage?.messageContent?.messageContent
@@ -206,11 +190,6 @@
                 {{ chatList[2]?.groupName }}
               </h1>
               <p class="line-clamp-1 h-20 text-sm text-black-6 leading-3xl">
-                <!-- {{
-                  chatList[2]?.lastMessage
-                    ? messageContentParse(chatList[2]?.lastMessage?.messageContent)
-                    : '暂无互动消息'
-                }} -->
                 {{
                   chatList[2]?.lastMessage
                     ? chatList[2]?.lastMessage?.messageContent?.messageContent
@@ -318,13 +297,14 @@
 import comments from '~/assets/img/chat/comments-white.svg'
 import plaza from '~/assets/img/chat/guangchang.svg'
 import userAdd from '~/assets/img/chat/user-add.svg'
+import scan from '~/assets/img/chat/scan.svg'
 
 import { XYWebSocket } from '~/utils/XYWebSocket.ts'
 
 const actionsList = [
   { text: '创建群聊', icon: comments },
   { text: '群聊广场', icon: plaza },
-  { text: '加入群聊', icon: plaza },
+  { text: '加入群聊', icon: scan },
   { text: '添加用户', icon: userAdd }
 ]
 const userInfoStore = useUserInfoStore()
@@ -335,8 +315,6 @@ const { chatList, chatListLoading } = storeToRefs(chatsStore)
 
 const showPopover = ref(false)
 
-const messagesNumber = ref(10)
-
 // 不置顶列表
 const pinnedList = computed(() => chatList.value.filter((el) => el.isTop != 1))
 
@@ -372,17 +350,17 @@ const onRefresh = () => {
 
 // 打扰和免打扰得
 const noBother = (parmas) => {
-  handleBoolean({ groupId: parmas.groupId, isNotDisturb: parmas.isNotDisturb })
+  handleBoolean({ groupId: parmas.groupId, isNotDisturb: parmas.isNotDisturb ? 0 : 1 })
 }
 
 // 是否置顶
 const onIsTop = (parmas) => {
-  handleBoolean({ groupId: parmas.groupId, isTop: parmas.isTop })
+  handleBoolean({ groupId: parmas.groupId, isTop: parmas.isTop ? 0 : 1 })
 }
 
 // 是否显示会话
 const onIsShow = (parmas) => {
-  handleBoolean({ groupId: parmas.groupId, isShow: parmas.isShow })
+  handleBoolean({ groupId: parmas.groupId, isShow: parmas.isShow == '1' ? 0 : 1 })
 }
 
 // 是否免打扰和 是否置顶 公共
@@ -469,8 +447,8 @@ const goDetails = (type, item) => {
       navigateTo({
         path: '/chat/group-chat',
         query: {
-          groupId: item?.groupId,
-          groupRemark: item?.groupRemark
+          groupId: item?.groupId
+          // groupRemark: item?.groupRemark
         }
       })
       break

+ 2 - 2
src/pages/profile/system-message/index.vue

@@ -3,8 +3,8 @@
     <ChatHeaderBar title="系统消息列表" />
     <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
       <div style="height: 100vh" class="pt-40">
-        <Empty v-if="!listData?.length && !loading" title="暂无系统消息" top="100" />
-
+        <!-- <Empty  title="" top="100" /> -->
+        <van-empty v-if="!listData?.length && !loading" description="暂无系统消息" />
         <van-list
           v-else-if="listData.length"
           v-model:loading="loading"

+ 0 - 195
src/pages/scan/test/_index.vue

@@ -1,195 +0,0 @@
-<script setup>
-import { Html5QrcodeScanner, Html5Qrcode, Html5QrcodeSupportedFormats, Html5QrcodeScanType } from 'html5-qrcode'
-const router = useRouter()
-definePageMeta({
-  layout: 'scan'
-})
-
-let scanInstance = null; // 扫码实例
-let results = ref(null); // 扫码结果
-
-const initScanInstance = () => {
-  if (!scanInstance) {
-    // reader放置扫码功能的元素ID
-    scanInstance = new Html5Qrcode('qr-reader', {
-      formatsToSupport: [
-        Html5QrcodeSupportedFormats.QR_CODE,
-      ],
-    })
-  }
-}
-const openQrcode = async () => {
-  Html5Qrcode.getCameras()
-      .then(devices => {
-        if (devices && devices.length) {// 当前环境下能识别出摄像头,并且摄像头的数据可能不止一个
-          initScanInstance()
-          scanInstance.start(
-              {facingMode: "environment"},
-              {
-                focusMode: 'continuous',
-                fps: 10, // 可选,每n秒帧扫描一次
-                qrbox: { // 扫描的UI框
-                  width: 250,
-                  height: 250
-                },
-                videoConstraints: {
-                  // width: 375,
-                  // height: (window.visualViewport.height - 50),
-                  aspectRatio: window.visualViewport.height / window.visualViewport.width,
-                  facingMode: "environment",
-                }
-              },
-              (decodedText, decodedResult) => {
-                showToast('识别成功')
-                handleSuccess({decodedText, decodedResult})
-              },
-              (errorMessage, error) => {
-                handleFail(errorMessage)
-              }
-          )
-        }
-      })
-      .catch((err) => {
-        // 错误信息处理仅供参考,具体情况看输出!!!
-        let errorStr = ''
-        if (typeof err === "string") {
-          errorStr = err
-        } else {
-          if (err.name === "NotAllowedError")
-            errorStr = "您需要授予相机访问权限"
-          if (err.name === "NotFoundError") {
-            errorStr = "未检测到摄像头"
-          }
-          if (err.name === "NotSupportedError")
-            errorStr = "摄像头访问只支持在安全的上下文中,如https或localhost"
-          if (err.name === "NotReadableError") errorStr = "摄像头被占用"
-          if (err.name === "OverconstrainedError")
-            errorStr = "安装摄像头不合适"
-          if (err.name === "StreamApiNotSupportedError")
-            errorStr = "此浏览器不支持流API"
-        }
-        showToast(errorStr)
-      })
-}
-const scanLoadImg = (e) => {
-  try {
-    initScanInstance()
-    scanInstance.scanFile(e.file, false)
-        .then(result => {
-          // 二维码结果
-          console.log(result, '上传扫码成功')
-          handleSuccess(result)
-        })
-        .catch(err => {
-          handleFail(err)
-        })
-  } catch (e) {
-    console.error(e, '失败')
-  }
-}
-
-const getResults = (result) => {
-
-  if (!result) {
-    return {success: false, groupId: null, overTime: false}
-  }
-
-  const url = new URL(result);
-  const urlParams = new URLSearchParams(url.search);
-
-  const hasGroupId = urlParams.has('groupId');
-  const hasTime = urlParams.has('time');
-  console.log(url.search, hasGroupId, hasTime, 'hasTime')
-  if (!hasGroupId || !hasTime) {
-    return {success: false, groupId: null, overTime: false}
-  }
-
-  const givenDate = new Date(urlParams.get('time'));
-  const currentDate = new Date();
-  const givenDateCst = new Date(givenDate.getTime() + (8 * 60 * 60 * 1000));
-  const currentDateCst = new Date(currentDate.getTime() + (8 * 60 * 60 * 1000));
-
-  const diffInMilliseconds = currentDateCst - givenDateCst;
-  const sevenDaysInMilliseconds = 7 * 24 * 60 * 60 * 1000;
-
-  return {
-    success: true,
-    groupId: urlParams.get('groupId'),
-    overTime: diffInMilliseconds > sevenDaysInMilliseconds
-  }
-}
-
-const handleSuccess = (result) => {
-  results.value = result
-  router.replace({
-    path: '/chat/qr-results',
-    query: result ? getResults(result) : result
-  })
-}
-
-const handleFail = (err) => {
-  alert(err)
-/*  router.replace({
-    path: '/chat/qr-results',
-    query: {success: false, groupId: null, overTime: false}
-  })*/
-}
-
-const closeQrcode = () => {
-  if (scanInstance && scanInstance.isScanning) scanInstance.stop()
-  router.back()
-}
-
-onMounted(async () => {
-  await nextTick()
-  // initScanInstance()
-  await openQrcode()
-})
-onUnmounted(() => {
-  if (scanInstance && scanInstance.isScanning) scanInstance.stop()
-})
-
-</script>
-
-<template>
-  <div>
-    <div v-if="false" class="h-200">
-      {{ results }}
-    </div>
-    <div class="overlay">
-      <div class="absolute w-full z-30 flex flex-row items-center justify-center p-12">
-        <div class="absolute left-12 font-bold" @click="closeQrcode">
-          <span class="iconfont icon-left text-white"></span>
-        </div>
-        <div class="text-base text-[#fff] font-bold">
-          扫描二维码
-        </div>
-      </div>
-      <div class="relative qr-reader z-20" id="qr-reader"></div>
-      <p class="absolute w-full p-12 text-center bottom-100 z-30 text-sm text-[#fff]">请将二维码对准扫码框中心</p>
-      <div id="qr-code-file"
-           class="absolute w-54 h-54 grid place-items-center bottom-40 z-30 rounded-full bg-[#000]/80 text-white left-1/2 -translate-x-1/2">
-        <van-uploader
-            :preview-image="false"
-            :after-read="scanLoadImg"
-            accept="image/*"
-            :multiple="false"
-            :max-count="1"
-        ><img src="../../../assets/img/scan/pic.png" height="32" width="32" alt=""/>
-        </van-uploader>
-      </div>
-    </div>
-  </div>
-</template>
-
-<style scoped lang="scss">
-.overlay {
-  position: fixed;
-  bottom: 0;
-  left: 0;
-  z-index: 999999;
-  width: 100%;
-  height: 100%;
-  background: rgba(0, 0, 0, 0.7);
-}
-</style>

+ 0 - 77
src/pages/scan/test/index.vue

@@ -1,77 +0,0 @@
-<template>
-  <div>
-    <div>{{res}}</div>
-    <!-- 扫描仪占位符 -->
-    <div id="reader"></div>
-  </div>
-</template>
-
-<script>
-import { Html5Qrcode } from "html5-qrcode"
-export default {
-  data() {
-    return {
-      res: null,
-      html5QrCode: null,
-    }
-  },
-  mounted() {
-    this.useCamera() // 打开相机
-  },
-  methods: {
-    // 关闭扫一扫页面,返回上一页
-    closed() {
-      this.html5QrCode.stop().finally(() => {
-        this.html5QrCode.clear()
-      })
-    },
-    scanRes(qr, err) {
-      this.res = qr
-    },
-    // 成功回调
-    onScanSuccess(qr) {
-      this.scanRes(qr)
-      this.closed()
-    },
-    useCamera() {
-      alert(1)
-      // 实例化,接收元素id作为参数
-      this.html5QrCode = new Html5Qrcode("reader")
-      // 获取相机设备
-      Html5Qrcode.getCameras()
-          .then(devices => {
-            // 扫码配置
-            const config = {
-              fps: 10, //  二维码扫描每秒帧数
-              qrbox: {
-                width: 300,
-                height: 300,
-              }, // UI框的大小
-              aspectRatio: 1.777778,
-            }
-            if (devices && devices.length) {
-              let cameraId = devices[devices.length - 1].id //后置摄像头,一般最后一个是后置摄像头
-              //let cameraId = devices[0].id //前置摄像头
-              this.html5QrCode
-                  .start({ deviceId: { exact: cameraId, }, }, config, this.onScanSuccess)
-                  .catch(err => {
-                    this.scanRes(undefined, err)
-                  })
-            } else {
-              // 如果没有找到设备,直接启用摄像头
-              //environment:后置摄像头  user:前置摄像头
-              this.html5QrCode
-                  .start( { facingMode: "environment" }, config, this.onScanSuccess )
-                  .catch(err => {
-                    alert('error')
-                    this.scanRes(undefined, err)
-                  })
-            }
-          })
-          .catch(err => {
-            this.scanRes(undefined, err)
-          })
-    },
-  },
-}
-</script>