import { defineStore } from 'pinia'; import { MessageApi, MessageMockData } from '/@/utils/messageApi'; // 消息类型 export interface MessageItem { id: number; title: string; content: string; type: number; // 1-系统通知,2-站内信,3-待办事项,4-公告通知 senderId: number; senderName: string; receiverId: number; receiverName: string; status: number; // 0-未读,1-已读,2-已删除 priority: number; // 0-普通,1-重要,2-紧急 bizType?: string; bizId?: number; readTime?: string; createTime: string; } // 消息类型枚举 export const MessageType = { SYSTEM: 1, // 系统通知 LETTER: 2, // 站内信 TODO: 3, // 待办事项 NOTICE: 4 // 公告通知 }; // 消息类型标签(从字典读取) import Session from '/@/utils/session'; const getDictLabel = (code: string, value: number): string => { const dicts = Session.get("dicts"); if (!dicts) return ''; const item = dicts[code]?.find((k: any) => k.value == value); return item?.name || ''; }; const getDictColor = (code: string, value: number): string => { const dicts = Session.get("dicts"); if (!dicts) return ''; const item = dicts[code]?.find((k: any) => k.value == value); return item?.color || ''; }; export const getMessageTypeLabel = (type: number) => getDictLabel('message_type', type); export const getPriorityLabel = (priority: number) => getDictLabel('priority', priority); export const getPriorityColor = (priority: number) => getDictColor('priority', priority); // 是否使用Mock数据 const useMock = true; /** * 消息通知 Store */ export const useMessageStore = defineStore('message', { state: () => ({ // 未读消息数量 unreadCount: 0, // 各类型未读数量 unreadCountByType: { 1: 0, // 系统通知 2: 0, // 站内信 3: 0, // 待办事项 4: 0 // 公告通知 } as Record, // 最新未读消息(用于下拉预览) latestMessages: [] as MessageItem[], // 消息列表(完整分页列表) messageList: [] as MessageItem[], // 分页信息 pagination: { pageNum: 1, pageSize: 10, total: 0 }, // 当前选中的消息类型筛选 currentType: null as number | null, // 轮询定时器 pollingTimer: null as any, // 是否正在加载 loading: false }), getters: { // 是否有未读消息 hasUnread: (state) => state.unreadCount > 0, // 获取某类型的未读数量 getUnreadByType: (state) => (type: number) => state.unreadCountByType[type] || 0 }, actions: { /** * 获取未读消息数量 */ async fetchUnreadCount() { try { if (useMock) { this.unreadCount = MessageMockData.unreadCount; this.unreadCountByType = { ...MessageMockData.unreadCountByType }; return; } const count = await MessageApi.getUnreadCount() as number; this.unreadCount = count; const countByType = await MessageApi.getUnreadCountByType() as Record; this.unreadCountByType = countByType; } catch (error) { console.error('获取未读消息数量失败:', error); // 使用Mock数据 this.unreadCount = MessageMockData.unreadCount; this.unreadCountByType = { ...MessageMockData.unreadCountByType }; } }, /** * 获取最新未读消息(用于下拉预览) */ async fetchLatestMessages(limit: number = 5) { try { if (useMock) { this.latestMessages = MessageMockData.list .filter(m => m.status === 0) .slice(0, limit); return; } const messages = await MessageApi.getLatestUnread(limit) as MessageItem[]; this.latestMessages = messages; } catch (error) { console.error('获取最新消息失败:', error); this.latestMessages = MessageMockData.list .filter(m => m.status === 0) .slice(0, limit); } }, /** * 获取消息列表(分页) */ async fetchMessageList(params?: { pageNum?: number; pageSize?: number; type?: number; status?: number; title?: string; }) { this.loading = true; try { const queryParams = { pageNum: params?.pageNum || this.pagination.pageNum, pageSize: params?.pageSize || this.pagination.pageSize, type: params?.type ?? this.currentType ?? undefined, status: params?.status, title: params?.title }; if (useMock) { let filteredList = [...MessageMockData.list]; if (queryParams.type) { filteredList = filteredList.filter(m => m.type === queryParams.type); } if (queryParams.status !== undefined) { filteredList = filteredList.filter(m => m.status === queryParams.status); } this.messageList = filteredList; this.pagination.total = filteredList.length; return; } const result = await MessageApi.getMessageList(queryParams) as any; this.messageList = result.list || []; this.pagination.total = result.total || 0; this.pagination.pageNum = queryParams.pageNum; this.pagination.pageSize = queryParams.pageSize; } catch (error) { console.error('获取消息列表失败:', error); let filteredList = [...MessageMockData.list]; if (params?.type) { filteredList = filteredList.filter(m => m.type === params.type); } this.messageList = filteredList; this.pagination.total = filteredList.length; } finally { this.loading = false; } }, /** * 标记单条消息已读 */ async markAsRead(messageId: number) { try { if (!useMock) { await MessageApi.markAsRead(messageId); } // 更新本地状态 const message = this.messageList.find(m => m.id === messageId); if (message && message.status === 0) { message.status = 1; message.readTime = new Date().toLocaleString(); this.unreadCount = Math.max(0, this.unreadCount - 1); if (this.unreadCountByType[message.type]) { this.unreadCountByType[message.type]--; } } // 更新最新消息列表 this.latestMessages = this.latestMessages.filter(m => m.id !== messageId); } catch (error) { console.error('标记已读失败:', error); } }, /** * 批量标记已读 */ async batchMarkAsRead(messageIds: number[]) { try { if (!useMock) { await MessageApi.batchMarkAsRead(messageIds); } // 更新本地状态 messageIds.forEach(id => { const message = this.messageList.find(m => m.id === id); if (message && message.status === 0) { message.status = 1; message.readTime = new Date().toLocaleString(); this.unreadCount = Math.max(0, this.unreadCount - 1); if (this.unreadCountByType[message.type]) { this.unreadCountByType[message.type]--; } } }); // 更新最新消息列表 this.latestMessages = this.latestMessages.filter(m => !messageIds.includes(m.id)); } catch (error) { console.error('批量标记已读失败:', error); } }, /** * 全部标记已读 */ async markAllAsRead(type?: number) { try { if (!useMock) { await MessageApi.markAllAsRead(type); } // 更新本地状态 this.messageList.forEach(message => { if (message.status === 0 && (!type || message.type === type)) { message.status = 1; message.readTime = new Date().toLocaleString(); } }); if (type) { this.unreadCount = Math.max(0, this.unreadCount - (this.unreadCountByType[type] || 0)); this.unreadCountByType[type] = 0; } else { this.unreadCount = 0; Object.keys(this.unreadCountByType).forEach(key => { this.unreadCountByType[Number(key)] = 0; }); } // 清空最新消息列表 if (!type) { this.latestMessages = []; } else { this.latestMessages = this.latestMessages.filter(m => m.type !== type); } } catch (error) { console.error('全部标记已读失败:', error); } }, /** * 删除消息 */ async deleteMessage(messageId: number) { try { if (!useMock) { await MessageApi.deleteMessage(messageId); } // 从列表中移除 const index = this.messageList.findIndex(m => m.id === messageId); if (index > -1) { const message = this.messageList[index]; if (message.status === 0) { this.unreadCount = Math.max(0, this.unreadCount - 1); if (this.unreadCountByType[message.type]) { this.unreadCountByType[message.type]--; } } this.messageList.splice(index, 1); this.pagination.total--; } // 从最新消息列表中移除 this.latestMessages = this.latestMessages.filter(m => m.id !== messageId); } catch (error) { console.error('删除消息失败:', error); } }, /** * 批量删除消息 */ async batchDeleteMessage(messageIds: number[]) { try { if (!useMock) { await MessageApi.batchDeleteMessage(messageIds); } // 从列表中移除 messageIds.forEach(id => { const index = this.messageList.findIndex(m => m.id === id); if (index > -1) { const message = this.messageList[index]; if (message.status === 0) { this.unreadCount = Math.max(0, this.unreadCount - 1); if (this.unreadCountByType[message.type]) { this.unreadCountByType[message.type]--; } } this.messageList.splice(index, 1); this.pagination.total--; } }); // 从最新消息列表中移除 this.latestMessages = this.latestMessages.filter(m => !messageIds.includes(m.id)); } catch (error) { console.error('批量删除消息失败:', error); } }, /** * 设置当前筛选类型 */ setCurrentType(type: number | null) { this.currentType = type; }, /** * 启动轮询(定时获取未读消息数量) * 注意:Mock模式下不启动轮询 */ startPolling(interval: number = 60000) { if (useMock) { // Mock模式下不需要轮询 return; } this.stopPolling(); this.fetchUnreadCount(); this.pollingTimer = setInterval(() => { this.fetchUnreadCount(); }, interval); }, /** * 停止轮询 */ stopPolling() { if (this.pollingTimer) { clearInterval(this.pollingTimer); this.pollingTimer = null; } }, /** * 初始化(登录后调用) */ async init() { await this.fetchUnreadCount(); await this.fetchLatestMessages(); this.startPolling(); }, /** * 清理(登出时调用) */ cleanup() { this.stopPolling(); this.unreadCount = 0; this.unreadCountByType = { 1: 0, 2: 0, 3: 0, 4: 0 }; this.latestMessages = []; this.messageList = []; } } });