Ver Fonte

feat: 修改未读置为已读的bug

zhouyuhao há 8 meses atrás
pai
commit
67acf852e1

+ 10 - 0
src/api/module/notificationMessage.ts

@@ -67,3 +67,13 @@ export const setMessageRead = (params: any) => {
     ...params
   })
 }
+
+/**
+ * 检测是否有新消息
+ */
+export const hasUnreadMessages = () => {
+  return HttpAxios.post(`${baseUrl}`, {
+    action: 'notifications_rules',
+    operate: 'check_notifications_message'
+  })
+}

+ 20 - 16
src/components/NotificationMessageCard/src/NotificationMessageCard.vue

@@ -4,7 +4,7 @@ import PasswordCard from './components/PasswordCard.vue'
 import FeatureUpdateCard from './components/FeatureUpdateCard.vue'
 import { useNotificationMessage } from '@/stores/modules/notificationMessage'
 
-const notificationMessageStore = useNotificationMessage()
+const notificationMsgStore = useNotificationMessage()
 const props = defineProps<{
   data: any
 }>()
@@ -22,13 +22,13 @@ const observer = new IntersectionObserver(
       const cardId = entry.target?.dataset?.cardId
       if (entry.isIntersecting) {
         // 将卡片设置为已经展示
-        notificationMessageStore.setReadCardMap(cardId)
+        notificationMsgStore.setReadCardMap(cardId)
         const index = props.data.findIndex((item) => item.info.id === cardId)
         if (index > -1) {
           //  在1秒钟后将消息卡片设置为已读
           setTimeout(() => {
             props.data[index].info.isRead = true
-          }, 1000)
+          }, 500)
         }
       }
     })
@@ -39,14 +39,15 @@ const observer = new IntersectionObserver(
     threshold: 0.1 // 当至少10%的元素进入视图时触发回调
   }
 )
-
+const curPageAllCards = ref()
 // 监听元素是否在可视区域内
 const watchCards = () => {
-  const curAllCards = document?.querySelectorAll('.notification-message-card')
-  curAllCards.forEach((card: any) => {
-    const index = notificationMessageStore.notificationMsgList.indexOf(card.dataset.cardId)
+  curPageAllCards.value = document?.querySelectorAll('.notification-message-card')
+  curPageAllCards.value.forEach((card: any) => {
+    const index = notificationMsgStore.notificationMsgList.indexOf(card.dataset.cardId)
+
     if (index < 0 && card.dataset.cardIsread === 'false' && card.dataset.cardId) {
-      notificationMessageStore.pushNotificationMessage([card.dataset.cardId])
+      notificationMsgStore.concatNotificationMsgList([card.dataset.cardId])
 
       observer.observe(card)
     }
@@ -59,7 +60,7 @@ watch(
     nextTick(() => {
       setTimeout(() => {
         watchCards()
-      }, 1000)
+      }, 500)
     })
   },
   {
@@ -70,17 +71,20 @@ watch(
 
 const clearReadData = () => {
   const idsToRemove = new Set(props.data.map((item: any) => item.info.id))
-  const filteredId = notificationMessageStore.notificationMsgList.filter(
-    (id) => !idsToRemove.has(id)
-  )
-  notificationMessageStore.pushNotificationMessage(filteredId)
+  const filteredId = notificationMsgStore.notificationMsgList.filter((id) => idsToRemove.has(id))
+  notificationMsgStore.removeNotificationMsgList(filteredId)
+
+  // 清除当前页面的所有卡片的监听
+  curPageAllCards.value.forEach((card: any) => {
+    observer.unobserve(card)
+  })
 }
 
 // 定时将消息卡片未读的置为已读
 let timer = null
 onMounted(() => {
   timer = setInterval(() => {
-    notificationMessageStore.markMessageAsRead()
+    notificationMsgStore.markMessageAsRead()
   }, 300000)
 })
 onUnmounted(() => {
@@ -94,8 +98,8 @@ onUnmounted(() => {
     class="notification-message-card"
     :data-card-id="item.info.id"
     :data-card-isread="item.info.isRead"
-    v-for="(item, index) in data"
-    :key="index"
+    v-for="item in data"
+    :key="item.info.id"
   >
     <EventCard @seeAll="handleSeeAll" v-if="item.notificationType === 'event'" :data="item.info" />
     <PasswordCard v-else-if="item.notificationType === 'password'" :data="item.info" />

+ 33 - 10
src/stores/modules/notificationMessage.ts

@@ -3,48 +3,71 @@ import { defineStore } from 'pinia'
 interface NotificationMessageState {
   notificationMsgList: string[] // 页面中监听的未读消息id
   readCardMap: string[] // 已读的消息id
-  requestedReadList: string[] // 已请求置为已读的消息id
+  hasNewMsg: boolean
 }
 
 export const useNotificationMessage = defineStore('notificationMessage', {
   state: (): NotificationMessageState => ({
     notificationMsgList: JSON.parse(localStorage.getItem('notificationMsgList')) || [],
     readCardMap: JSON.parse(localStorage.getItem('readCardMap')) || [],
-    requestedReadList: JSON.parse(localStorage.getItem('requestedReadList')) || []
+    hasNewMsg: JSON.parse(localStorage.getItem('hasNewMsg')) || false
   }),
   getters: {},
   actions: {
-    pushNotificationMessage(array: any[]) {
-      this.notificationMsgList = [...this.notificationMsgList, ...array]
+    concatNotificationMsgList(array: any[]) {
+      this.notificationMsgList = [...new Set([...this.notificationMsgList, ...array])]
+      localStorage.setItem('notificationMsgList', JSON.stringify(this.notificationMsgList))
+    },
+    removeNotificationMsgList(array: any[]) {
+      this.notificationMsgList = this.notificationMsgList.filter((item) => !array.includes(item))
       localStorage.setItem('notificationMsgList', JSON.stringify(this.notificationMsgList))
     },
     setReadCardMap(id: string) {
-      if (this.readCardMap.includes(id) || this.requestedReadList.includes(id)) return
+      if (this.readCardMap.includes(id)) return
       this.readCardMap.push(id)
       localStorage.setItem('readCardMap', JSON.stringify(this.readCardMap))
+      this.notificationMsgList = this.notificationMsgList.filter((item) => {
+        return !this.readCardMap.includes(item)
+      })
+      localStorage.setItem('notificationMsgList', JSON.stringify(this.notificationMsgList))
+    },
+    hasUnreadMessages() {
+      $api.hasUnreadMessages().then((res) => {
+        if (res.code === 200) {
+          // this.hasNewMsg = res.data.has_message
+          this.hasNewMsg = false
+          localStorage.setItem('hasNewMsg', JSON.stringify(this.hasNewMsg))
+        }
+      })
     },
     markMessageAsRead() {
       if (this.readCardMap.length === 0) return
-      $api.setMessageRead({ id: this.readCardMap }).then((res) => {
+
+      // this.readCardMap = []
+      // localStorage.setItem('readCardMap', JSON.stringify(this.readCardMap))
+
+      // { id: this.readCardMap }
+      $api.setMessageRead().then((res) => {
         if (res.code === 200) {
-          this.requestedReadList = this.readCardMap
-          localStorage.setItem('requestedReadList', JSON.stringify(this.requestedReadList))
           this.readCardMap = []
           localStorage.setItem('readCardMap', JSON.stringify(this.readCardMap))
 
           this.notificationMsgList = this.notificationMsgList.filter(
             (item) => !this.readCardMap.includes(item.id)
           )
+          localStorage.setItem('notificationMsgList', JSON.stringify(this.notificationMsg))
+          // 在将消息标记为已读后,再次检查是否有新消息
+          this.hasUnreadMessages()
         }
       })
     },
     clearData() {
       this.notificationMsgList = []
       this.readCardMap = []
-      this.requestedReadList = []
+      this.hasNewMsg = false
+      localStorage.removeItem('hasNewMsg')
       localStorage.removeItem('notificationMsgList')
       localStorage.removeItem('readCardMap')
-      localStorage.removeItem('requestedReadList')
     }
   }
 })

+ 11 - 6
src/views/Layout/src/components/Header/HeaderView.vue

@@ -8,9 +8,11 @@ import { useHeaderSearch } from '@/stores/modules/headerSearch'
 import { onBeforeRouteUpdate } from 'vue-router'
 import { useLoadingState } from '@/stores/modules/loadingState'
 import { useThemeStore } from '@/stores/modules/theme'
+import { useNotificationMessage } from '@/stores/modules/notificationMessage'
 import NotificationDrawer from './components/NotificationDrawer.vue'
 import TrainingCard from './components/TrainingCard.vue'
 
+const notificationMsgStore = useNotificationMessage()
 const themeStore = useThemeStore()
 const userStore = useUserStore()
 const route = useRoute()
@@ -180,10 +182,13 @@ const closePopover = () => {
 
 const notificationDrawer = ref(false)
 
-const hasNewMessage = ref(false)
-const notifyNewMessage = () => {
-  hasNewMessage.value = true
-}
+onBeforeRouteUpdate((to, from, next) => {
+  if (from.name === 'Login' && userStore.userName) {
+    notificationMsgStore.hasUnreadMessages()
+  }
+
+  next()
+})
 </script>
 
 <template>
@@ -195,7 +200,7 @@ const notifyNewMessage = () => {
     element-loading-background="rgb(43, 47, 54, 0.7)"
   >
     <VBreadcrumb></VBreadcrumb>
-    <TrainingCard ref="trainingCardRef" @has-new-message="notifyNewMessage"></TrainingCard>
+    <TrainingCard ref="trainingCardRef"></TrainingCard>
     <div class="right-info">
       <el-input
         v-model="searchValue"
@@ -208,7 +213,7 @@ const notifyNewMessage = () => {
         </template>
       </el-input>
       <div class="notice-icon" v-if="userStore.userInfo?.uname">
-        <span v-if="hasNewMessage" class="unread-tip-icon"></span>
+        <span v-if="notificationMsgStore.hasNewMsg" class="unread-tip-icon"></span>
         <el-button
           style="height: 40px; width: 40px; margin-right: 0px"
           class="el-button--text"

+ 7 - 1
src/views/Layout/src/components/Header/components/NotificationDrawer.vue

@@ -126,6 +126,7 @@ const handleSettingMessage = () => {
 
 const clearData = () => {
   notificationList.value = []
+  notificationType.value = 'all'
 }
 
 const notificationListRef = ref<HTMLElement | null>(null)
@@ -140,7 +141,12 @@ const notificationListRef = ref<HTMLElement | null>(null)
     size="432px"
   >
     <template #header>
-      <el-select size="large" v-model="notificationType" class="notification-type">
+      <el-select
+        size="large"
+        @change="getNotificationList"
+        v-model="notificationType"
+        class="notification-type"
+      >
         <el-option
           v-for="(label, value) in notificationTypeList"
           :key="value"

+ 2 - 4
src/views/Layout/src/components/Header/components/TrainingCard.vue

@@ -6,7 +6,7 @@ import { useNotificationMessage } from '@/stores/modules/notificationMessage'
 import dayjs from 'dayjs'
 
 const userStore = useUserStore()
-const notificationMessageStore = useNotificationMessage()
+const notificationMsgStore = useNotificationMessage()
 const notificationList = ref([])
 // const notificationList = [
 //   {
@@ -176,7 +176,6 @@ onBeforeRouteUpdate((to, from, next) => {
   next()
 })
 
-const emit = defineEmits<{ hasNewMessage: [] }>()
 const getNotificationList = (time?: string) => {
   $api
     .getNotificationList({
@@ -190,7 +189,6 @@ const getNotificationList = (time?: string) => {
         notificationList.value = res.data
 
         if (time && res.data.length > 0) {
-          emit('hasNewMessage')
           initTrainingCard()
         } else {
           trainingIntervalId = setInterval(trainingCardAfterLogin, 2000)
@@ -218,7 +216,7 @@ const closeMessage = () => {
     trainingIntervalId = setInterval(nextNotification, 2000)
   }
   // 将当前消息标记为已读
-  notificationMessageStore.setReadCardMap(curCard.value?.info?.id)
+  notificationMsgStore.setReadCardMap(curCard.value?.info?.id)
 }
 </script>
 

+ 14 - 5
src/views/SystemMessage/src/SystemMessage.vue

@@ -2,7 +2,7 @@
 import NotificationMessageCard from '@/components/NotificationMessageCard/src/NotificationMessageCard.vue'
 import { useNotificationMessage } from '@/stores/modules/notificationMessage'
 
-const notificationMessageStore = useNotificationMessage()
+const notificationMsgStore = useNotificationMessage()
 const collapseVModel = ref<string[]>(['1'])
 
 const tabCountList = ref([0, 0, 0, 0, 0])
@@ -82,7 +82,7 @@ onMounted(() => {
   getNotificationList()
 })
 onUnmounted(() => {
-  notificationMessageStore.markMessageAsRead()
+  notificationMsgStore.markMessageAsRead()
 })
 </script>
 
@@ -128,7 +128,10 @@ onUnmounted(() => {
               <span style="margin-right: 4px">All Notifications</span>
             </template>
             <div style="padding: 10px 140px 0px 16px" v-if="activeName === 'All Notifications'">
-              <NotificationMessageCard :data="notificationList"></NotificationMessageCard>
+              <NotificationMessageCard
+                key="All Notifications"
+                :data="notificationList"
+              ></NotificationMessageCard>
             </div>
           </el-tab-pane>
           <el-tab-pane label="Unread" name="Unread">
@@ -139,13 +142,19 @@ onUnmounted(() => {
               </div>
             </template>
             <div style="padding: 10px 140px 0px 16px" v-if="activeName === 'Unread'">
-              <NotificationMessageCard :data="unreadNotificationList"></NotificationMessageCard>
+              <NotificationMessageCard
+                key="Unread"
+                :data="unreadNotificationList"
+              ></NotificationMessageCard>
             </div>
           </el-tab-pane>
           <el-tab-pane label="Read" name="Read">
             <template #label><span style="margin-right: 4px">Read</span> </template>
             <div style="padding: 10px 140px 0px 16px" v-if="activeName === 'Read'">
-              <NotificationMessageCard :data="readNotificationList"></NotificationMessageCard>
+              <NotificationMessageCard
+                key="Read"
+                :data="readNotificationList"
+              ></NotificationMessageCard>
             </div>
           </el-tab-pane>
         </el-tabs>