update 消息推送增加 消息类型 消息来源 前端跳转路径等扩展参数

This commit is contained in:
疯狂的狮子Li
2026-03-26 15:34:02 +08:00
parent 05527965e2
commit 42f63fbe24
5 changed files with 123 additions and 29 deletions
+23 -4
View File
@@ -8,8 +8,9 @@
<template v-if="newsList.length > 0">
<div v-for="(v, k) in newsList" :key="k" class="content-box-item" @click="onNewsClick(k)">
<div class="item-conten">
<div class="content-box-title">{{ v.title || '消息' }}</div>
<div>{{ v.message }}</div>
<div class="content-box-msg"></div>
<div v-if="v.content" class="content-box-msg">{{ v.content }}</div>
<div class="content-box-time">{{ v.time }}</div>
</div>
<!-- 已读/未读 -->
@@ -25,6 +26,7 @@
<script setup lang="ts" name="layoutBreadcrumbUserNews">
import { useNoticeStore } from '@/store/modules/notice';
import router from '@/router';
const noticeStore = useNoticeStore();
const { readAll } = useNoticeStore();
@@ -46,10 +48,17 @@ const getTableData = async () => {
};
//点击消息,写入已读
const onNewsClick = (item: any) => {
const onNewsClick = async (item: any) => {
newsList.value[item].read = true;
//并且写入pinia
noticeStore.state.notices = newsList.value;
const current = newsList.value[item];
if (current?.path) {
await router.push({
path: current.path,
query: current.query || undefined
});
}
};
// 前往通知中心点击
@@ -123,8 +132,12 @@ onMounted(() => {
.content-box-msg {
color: var(--el-text-color-secondary);
margin-top: 5px;
margin-bottom: 5px;
margin: 2px 0 0;
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.content-box-time {
@@ -141,6 +154,12 @@ onMounted(() => {
line-height: 1.6;
}
.content-box-title {
font-size: 12px;
font-weight: 600;
color: var(--app-accent-strong);
}
.read {
flex-shrink: 0;
margin-top: 2px;
+8 -2
View File
@@ -1,10 +1,16 @@
import { defineStore } from 'pinia';
import { reactive } from 'vue';
interface NoticeItem {
export interface NoticeItem {
title?: string;
type?: string;
source?: string;
read: boolean;
message: any;
message: string;
content?: string;
data?: Record<string, any> | null;
path?: string;
query?: Record<string, any> | null;
time: string;
}
+47
View File
@@ -0,0 +1,47 @@
export const PUSH_MESSAGE_TYPE = {
MESSAGE: 'message',
NOTICE: 'notice',
LLM: 'llm',
CUSTOM: 'custom'
} as const;
export interface PushMessagePayload {
type?: string;
source?: string;
message?: string;
data?: Record<string, any> | null;
path?: string;
query?: Record<string, any> | null;
timestamp?: number;
}
const MESSAGE_CENTER_TYPES = new Set<string>([PUSH_MESSAGE_TYPE.MESSAGE, PUSH_MESSAGE_TYPE.NOTICE]);
export const parsePushMessage = (raw: string): PushMessagePayload => {
try {
const payload = JSON.parse(raw) as PushMessagePayload;
return {
type: payload.type ?? PUSH_MESSAGE_TYPE.MESSAGE,
source: payload.source ?? 'backend',
message: payload.message ?? '',
data: payload.data ?? null,
path: payload.path,
query: payload.query ?? null,
timestamp: payload.timestamp ?? Date.now()
};
} catch {
return {
type: PUSH_MESSAGE_TYPE.MESSAGE,
source: 'backend',
message: raw,
data: null,
path: undefined,
query: null,
timestamp: Date.now()
};
}
};
export const shouldAppendNotice = (payload: PushMessagePayload) => {
return MESSAGE_CENTER_TYPES.has(payload.type ?? PUSH_MESSAGE_TYPE.MESSAGE);
};
+22 -11
View File
@@ -1,6 +1,7 @@
import { getToken } from '@/utils/auth';
import { ElNotification } from 'element-plus';
import { useNoticeStore } from '@/store/modules/notice';
import { parsePushMessage, PUSH_MESSAGE_TYPE, shouldAppendNotice } from '@/utils/push-message';
// 初始化
export const initSSE = (url: any) => {
@@ -26,17 +27,27 @@ export const initSSE = (url: any) => {
watch(data, () => {
if (!data.value) return;
useNoticeStore().addNotice({
message: data.value,
read: false,
time: new Date().toLocaleString()
});
ElNotification({
title: '消息',
message: data.value,
type: 'success',
duration: 3000
});
const payload = parsePushMessage(data.value);
if (shouldAppendNotice(payload)) {
useNoticeStore().addNotice({
title: payload.type === PUSH_MESSAGE_TYPE.NOTICE ? '通知公告' : '系统消息',
type: payload.type,
source: payload.source,
message: payload.message ?? '',
content: payload.data?.noticeContent,
data: payload.data,
path: payload.path,
query: payload.query,
read: false,
time: new Date(payload.timestamp ?? Date.now()).toLocaleString()
});
ElNotification({
title: payload.type === PUSH_MESSAGE_TYPE.NOTICE ? '通知公告' : '消息',
message: payload.message ?? '',
type: 'success',
duration: 3000
});
}
data.value = null;
});
};
+23 -12
View File
@@ -1,6 +1,7 @@
import { getToken } from '@/utils/auth';
import { ElNotification } from 'element-plus';
import { useNoticeStore } from '@/store/modules/notice';
import { parsePushMessage, PUSH_MESSAGE_TYPE, shouldAppendNotice } from '@/utils/push-message';
// 初始化socket
export const initWebSocket = (url: any) => {
@@ -32,20 +33,30 @@ export const initWebSocket = (url: any) => {
console.log('websocket已经断开');
},
onMessage: (_, e) => {
if (e.data.indexOf('ping') > 0) {
if (typeof e.data === 'string' && e.data.includes('ping')) {
return;
}
useNoticeStore().addNotice({
message: e.data,
read: false,
time: new Date().toLocaleString()
});
ElNotification({
title: '消息',
message: e.data,
type: 'success',
duration: 3000
});
const payload = parsePushMessage(String(e.data));
if (shouldAppendNotice(payload)) {
useNoticeStore().addNotice({
title: payload.type === PUSH_MESSAGE_TYPE.NOTICE ? '通知公告' : '系统消息',
type: payload.type,
source: payload.source,
message: payload.message ?? '',
content: payload.data?.noticeContent,
data: payload.data,
path: payload.path,
query: payload.query,
read: false,
time: new Date(payload.timestamp ?? Date.now()).toLocaleString()
});
ElNotification({
title: payload.type === PUSH_MESSAGE_TYPE.NOTICE ? '通知公告' : '消息',
message: payload.message ?? '',
type: 'success',
duration: 3000
});
}
}
});
};