zhouxiantao
8 days ago 03193b2a27a2c23e10f3a2f298de9c1142116780
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/**
 * @author 韩天尊
 * @time 2024-01-15
 * @version 1.0.0
 * @description 消息列表页面组件
 */
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAppContext } from '../context/AppContext';
import { messageAPI } from '../services/api';
import PageHeader from '../components/PageHeader';
import { format } from 'date-fns';
 
const MessageListPage: React.FC = () => {
    const navigate = useNavigate();
    const { state, loadMessages, markMessageRead } = useAppContext();
    const [activeTab, setActiveTab] = useState<'all' | 'system' | 'activity'>('all');
    const [loading, setLoading] = useState(false);
 
    // 加载消息数据
    useEffect(() => {
        const loadMessagesData = async () => {
            setLoading(true);
            try {
                await loadMessages({ userId: state.user?.id });
            } catch (error) {
                console.error('加载消息失败:', error);
            } finally {
                setLoading(false);
            }
        };
 
        if (state.user?.id) {
            loadMessagesData();
        }
    }, [state.user?.id, loadMessages]);
 
    // 处理Tab切换
    const handleTabChange = (tab: 'all' | 'system' | 'activity') => {
        setActiveTab(tab);
    };
 
    // 处理消息点击
    const handleMessageClick = async (message: any) => {
        if (!message.isRead) {
            await markMessageRead(message.id);
        }
        navigate(`/message-detail/${message.id}`);
    };
 
    // 获取消息类型文本
    const getMessageTypeText = (type: string) => {
        switch (type) {
            case '1': return '系统消息';
            case '2': return '活动消息';
            default: return '系统消息';
        }
    };
 
    // 格式化时间
    const formatMessageTime = (timeStr?: string) => {
        if (!timeStr) return '时间未知';
        
        try {
            const date = new Date(timeStr);
            return format(date, 'yyyy-MM-dd HH:mm');
        } catch (error) {
            console.error('时间格式化失败:', error);
            return timeStr;
        }
    };
 
    // 过滤消息
    const getFilteredMessages = () => {
        let filtered = state.messages;
        
        switch (activeTab) {
            case 'system':
                filtered = filtered.filter(msg => msg.type === '1');
                break;
            case 'activity':
                filtered = filtered.filter(msg => msg.type === '2');
                break;
            case 'all':
            default:
                filtered = filtered;
                break;
        }
        
        return filtered;
    };
 
    const filteredMessages = getFilteredMessages();
 
    return (
        <div className="page">
            <PageHeader title="我的消息" showBack={true} />
 
            {/* 消息类型筛选 */}
            <div className="declaration-tabs">
                <button 
                    className={`declaration-tab ${activeTab === 'all' ? 'active' : ''}`}
                    onClick={() => handleTabChange('all')}
                >
                    全部
                </button>
                <button 
                    className={`declaration-tab ${activeTab === 'system' ? 'active' : ''}`}
                    onClick={() => handleTabChange('system')}
                >
                    系统消息
                </button>
                <button 
                    className={`declaration-tab ${activeTab === 'activity' ? 'active' : ''}`}
                    onClick={() => handleTabChange('activity')}
                >
                    活动消息
                </button>
            </div>
 
            {/* 消息列表 */}
            <div className="message-list">
                {loading ? (
                    <div className="loading-container">
                        <div className="loading-spinner"></div>
                        <p>加载中...</p>
                    </div>
                ) : filteredMessages.length === 0 ? (
                    <div className="empty-state">
                        <i className="fas fa-inbox"></i>
                        <p>暂无消息</p>
                    </div>
                ) : (
                    filteredMessages.map((message) => (
                        <div 
                            key={message.id} 
                            className={`message-item ${message.isRead ? 'read' : 'unread'}`}
                            onClick={() => handleMessageClick(message)}
                        >
                            <div className="message-header">
                                <div className="message-title">{message.title}</div>
                                <div className={`message-status ${message.isRead ? 'read' : 'unread'}`}>
                                    {message.isRead ? '已读' : '未读'}
                                </div>
                            </div>
                            <div className="message-preview">
                                {message.content && message.content.length > 50 
                                    ? `${message.content.substring(0, 50)}...` 
                                    : message.content}
                            </div>
                            <div className="message-meta">
                                <span className="message-time">{formatMessageTime(message.createTime || message.time)}</span>
                                <span className="message-type">{getMessageTypeText(message.type)}</span>
                            </div>
                        </div>
                    ))
                )}
            </div>
        </div>
    );
};
 
export default MessageListPage;