后台管理系统消息通知模块
摘要:Pinia 实现状态管理 import { defineStore } from 'pinia' import { createPersistedState } from 'pinia-plugin-persistedstate' export const useMessageStore = defineStore('message', { state: ( => ({ messageList: [], approvalList: [], showMsgCount: 0, showAprCount: 0 } , getters: { getMessageList: (state =<!--autointro-->...
Pinia 实现状态管理
import { defineStore } from 'pinia'
import { createPersistedState } from 'pinia-plugin-persistedstate'
export const useMessageStore = defineStore('message', {
state: () => ({
messageList: [],
approvalList: [],
showMsgCount: 0,
showAprCount: 0
}),
getters: {
getMessageList: (state) => state.messageList,
getShowMsgCount: (state) => state.showMsgCount,
getApprovalList: (state) => state.approvalList,
getShowAprCount: (state) => state.showAprCount
},
actions: {
// 用于添加单条消息到messageList
addMessageToMessageList(message) {
this.messageList.push(message)
this.updateShowMsgCount()
},
// 用于批量添加消息到messageList
addMessagesToMessageList(messages) {
this.messageList = [...this.messageList, ...messages]
this.updateShowMsgCount()
},
// 移除单条消息
removeMessageFromList(messageId) {
this.messageList = this.messageList.filter(item => item.id !== messageId)
this.updateShowMsgCount()
},
// 移除多条消息
removeMessagesFromList(messageIds) {
this.messageList = this.messageList.filter(item => !messageIds.includes(item.id))
this.updateShowMsgCount()
},
// 更新消息条数showMsgCount
updateShowMsgCount() {
this.showMsgCount = this.messageList.length
},
// 清空消息列表
clearMessageList() {
this.messageList = []
this.showMsgCount = 0
},
/** ===================审批提醒====================== */
// 用于添加单条审批消息到approvalList
addAprToApprovalList(message) {
this.approvalList.push(message)
this.updateShowAprCount()
},
// 用于批量添加审批消息到approvalList
addAprsToApprovalList(messages) {
this.approvalList = [...this.approvalList, ...messages]
this.updateShowAprCount()
},
// 移除单条审批消息
removeAprFromList(approvalId) {
this.approvalList = this.approvalList.filter(item => item.id !== approvalId)
this.updateShowAprCount()
},
// 移除多条审批消息
removeAprsFromList(approvalIds) {
this.approvalList = this.approvalList.filter(item => !approvalIds.includes(item.id))
this.updateShowAprCount()
},
// 更新审批消息条数showAprCount
updateShowAprCount() {
this.showAprCount = this.approvalList.length
},
// 清空审批消息列表
clearApprovalList() {
this.approvalList = []
this.showAprCount = 0
}
},
// 添加持久化配置
persist: {
enabled: true,
strategies: [
{
key: 'Admin-message-store',
storage: localStorage,
paths: ['messageList', 'approvalList', 'showMsgCount', 'showAprCount'],
// 序列化 或者进行加密操作
serializer: {
serialize: (state) => JSON.stringify(state),
deserialize: (str) => JSON.parse(str)
}
}
]
}
})
消息通知页面
<template>
<el-dropdown trigger="click" >
<el-badge :value="showMsgCount" :hidden="showMsgCount <= 0" :style="{ opacity }" :max="99" class="item" @click="handleClick">
<el-icon
color="currentColor"
class="el-icon-bell"
:size="20"
style="vertical-align: middle"
>
<Bell />
</el-icon>
</el-badge>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item v-for="(msg, index) in messageList" :key="index" @click="goToPage(msg.url)">
<el-icon style="color: red;"><Message /></el-icon>{{msg.content}}
</el-dropdown-item>
<el-dropdown-item @click="goToAllMessagesPage" class="message-item"><el-icon style="color: red;"><Message /></el-icon>查看所有消息</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
<script setup>
import { ref, watch, watchEffect } from "vue";
import { onBeforeUnmount } from "vue";
import { useMessageStore } from '@/store/modules/message'
import { computed } from "vue";
const messageStore = useMessageStore()
const opacity = ref(1);
let timer = null;
// 从store获取messageList和showMsgCount
const messageList = computed(() => messageStore.getMessageList)
const showMsgCount = computed(() => messageStore.getShowMsgCount)
const goToPage = (url) => {
// 这里可根据实际路由情况进行跳转,假设使用vue-router
// 需先引入router并配置好路由
// import { useRouter } from 'vue-router'
// const router = useRouter()
// router.push(url)
console.log(`跳转到: ${url}`)
}
const goToAllMessagesPage = () => {
// 同样需根据实际路由情况进行跳转
// import { useRouter } from 'vue-router'
// const router = useRouter()
// router.push('/all-messages')
console.log('跳转到所有消息页面')
}
const changeOpacity = () => {
if(showMsgCount.value === 0) return
timer = setInterval(() => {
if (opacity.value == 0) opacity.value = 1;
else opacity.value = 0;
}, 700);
};
const handleClick = () => {
opacity.value = 1;
clearInterval(timer);
timer = null;
};
watchEffect(() => {
if (showMsgCount.value > 0) {
if (!timer) {
changeOpacity()
}
} else {
clearInterval(timer)
timer = null
}
})
// ======================= WebSocket =========================
import { useSocket } from '@/utils/websocket'
const { on } = useSocket();
// 监听消息事件
on('message', (data) => {
console.log('收到消息:', data);
if(data && data.data && data.type == 'notification') {
// 如果是通知类型的消息,添加到通知消息列表
messageStore.addMessageToMessageList({
id: data.id || Date.now(), // 使用data.id或当前时间戳作为唯一标识
content: data.data,
url: '' // 默认跳转链接
});
} else if(data && data.data && data.type == 'message') {
// 如果是审批消息类型,添加到审批消息列表
messageStore.addAprToApprovalList({
id: data.id || Date.now(), // 使用data.id或当前时间戳作为唯一标识
content: data.data,
url: '' // 默认跳转链接
});
}
});
// ======================== WebSocket =========================
onBeforeUnmount(() => {
clearInterval(timer);
timer = null;
});
</script>
<style lang="scss" scoped>
.item {
position: relative;
transition: all 0.5s ease;
}
::v-deep(.el-dropdown-menu) {
font-size: 12px;
}
::v-deep(.el-dropdown-menu__item){
height: 40px ;
line-height: 40px ;
padding: 10px 20px;
width: 250px;
border-bottom: 1px solid #f0f0f0;
color: inherit;
cursor: pointer;
&:hover {
background-color: #f5f5f5;
}
}
::v-deep(.el-dropdown-menu__item):last-child {
border-bottom: none;
}
</style>
websocket 相关代码请点击传送门前往查看 传送门
本文链接:https://blog.smallhao.fun/?id=31 转载需授权!
Chen’Blog版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!