| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- 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<number, number>,
- // 最新未读消息(用于下拉预览)
- 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<number, number>;
- 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 = [];
- }
- }
- });
|