first commit
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
import { ref } from 'vue';
|
||||
import * as signalR from '@microsoft/signalr';
|
||||
import { getAccessToken } from './request';
|
||||
import request from './request';
|
||||
|
||||
// 全局未读数量(layout 徽章 与 消息页共用)
|
||||
export const unreadCount = ref(0);
|
||||
|
||||
let connection = null;
|
||||
const messageHandlers = [];
|
||||
const businessChangeHandlers = [];
|
||||
|
||||
/** 加载未读数量 */
|
||||
export async function loadUnreadCount() {
|
||||
try {
|
||||
const res = await request.get('/notification/unread-count');
|
||||
unreadCount.value = res.data.count;
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 SignalR 通知连接(幂等,重复调用返回同一连接)
|
||||
* @param {Function} onMessage 收到新消息时的回调 (msg) => void
|
||||
*/
|
||||
export function initNotification(onMessage) {
|
||||
if (connection) {
|
||||
if (onMessage) messageHandlers.push(onMessage);
|
||||
return connection;
|
||||
}
|
||||
|
||||
if (onMessage) messageHandlers.push(onMessage);
|
||||
|
||||
connection = new signalR.HubConnectionBuilder()
|
||||
.withUrl('/hubs/notification', {
|
||||
accessTokenFactory: () => getAccessToken() || ''
|
||||
})
|
||||
.withAutomaticReconnect()
|
||||
.configureLogging(signalR.LogLevel.Warning)
|
||||
.build();
|
||||
|
||||
connection.on('ReceiveNotification', (msg) => {
|
||||
unreadCount.value++; // 全局未读 +1
|
||||
messageHandlers.forEach((h) => { try { h(msg); } catch (e) {} });
|
||||
});
|
||||
|
||||
// 业务状态变更事件(多端同步:某端操作后,其它端刷新已打开的页面)
|
||||
connection.on('BusinessChanged', (e) => {
|
||||
businessChangeHandlers.forEach((h) => { try { h(e); } catch (err) {} });
|
||||
});
|
||||
|
||||
connection.start().catch(() => {});
|
||||
return connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* 订阅业务状态变更事件(用于多端同步刷新)。
|
||||
* @param {Function} handler (e) => void,e 含 businessType / businessId / action
|
||||
*/
|
||||
export function onBusinessChanged(handler) {
|
||||
if (handler) businessChangeHandlers.push(handler);
|
||||
initNotification(); // 确保连接已建立(幂等)
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开消息:标记已读 + 跳转到业务页面(消息自带 routePath 时)。
|
||||
* @param {Object} msg 消息对象(含 id/readStatus/routePath/category)
|
||||
* @param {Object} router vue-router 实例
|
||||
* @returns {boolean} 是否发生了页面跳转
|
||||
*/
|
||||
export async function openMessage(msg, router) {
|
||||
// 待办消息(category=1)点击"去处理"不标记已读,保持未读提醒;
|
||||
// 只有真正完成待办后(后端完成待办时会标记已读)才消失
|
||||
if (msg.readStatus === 0 && msg.category !== 1) {
|
||||
try {
|
||||
await request.put(`/notification/messages/${msg.id}/read`);
|
||||
msg.readStatus = 1;
|
||||
loadUnreadCount();
|
||||
} catch (e) {}
|
||||
}
|
||||
if (msg.routePath) {
|
||||
router.push(msg.routePath);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** 停止连接(登出时调用) */
|
||||
export function stopNotification() {
|
||||
if (connection) {
|
||||
connection.stop().catch(() => {});
|
||||
connection = null;
|
||||
}
|
||||
messageHandlers.length = 0;
|
||||
unreadCount.value = 0;
|
||||
}
|
||||
|
||||
export function getNotificationConnection() {
|
||||
return connection;
|
||||
}
|
||||
Reference in New Issue
Block a user