/** * YichensBoard - 一尘看板页面 * Version: 1.2.70x * 更新: */ import React, { useState, useEffect } from 'react' export default function YichensBoard() { const [todayStats, setTodayStats] = useState({ total: 0, deals: 0, wants: 0, others: 0 }) const [todayCategory, setTodayCategory] = useState([]) const [posts, setPosts] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [expandedPosts, setExpandedPosts] = useState({}) const [postTypeFilter, setPostTypeFilter] = useState('all') const [categoryFilter, setCategoryFilter] = useState('') const [numberFilter, setNumberFilter] = useState('') const [page, setPage] = useState(1) const [totalPosts, setTotalPosts] = useState(0) const [searchKeyword, setSearchKeyword] = useState('') const today = new Date() const dateStr = today.getFullYear() + '/' + (today.getMonth() + 1) + '/' + today.getDate() useEffect(() => { console.log('YichensBoard: 开始加载数据') fetchTodayStats() }, []) const fetchTodayStats = async () => { try { console.log('YichensBoard: 请求 /api/yichens/stats/today') const res = await fetch('/api/yichens/stats/today') if (!res.ok) throw new Error('stats API error: ' + res.status) const data = await res.json() console.log('YichensBoard: stats data', data) setTodayStats(data) } catch(e) { console.error('YichensBoard: fetchTodayStats error', e) setError(e.message) } } const fetchPosts = async (p, cat, kw, numFilter) => { setLoading(true) setError(null) const currentPage = p !== undefined ? p : page const currentCat = cat !== undefined ? cat : categoryFilter const searchKw = kw !== undefined ? kw : searchKeyword const numFilterVal = numFilter !== undefined ? numFilter : numberFilter let url = '/api/yichens/posts?limit=390&offset=' + ((currentPage - 1) * 390) if (postTypeFilter === 'deal') url += '&post_type=deal' else if (postTypeFilter === 'want') url += '&post_type=want' else if (postTypeFilter === 'other') url += '&post_type=normal' if (searchKw && searchKw.trim()) url += '&keyword=' + encodeURIComponent(searchKw.trim()) if (numFilterVal && numFilterVal !== '') url += '&number_filter=' + encodeURIComponent(numFilterVal) try { console.log('YichensBoard: 请求 posts', url) const res = await fetch(url) if (!res.ok) throw new Error('posts API error: ' + res.status) let data = await res.json() || [] // 确保data是数组 if (!Array.isArray(data)) { data = data.posts || data.data || [] } console.log('YichensBoard: posts data count', data.length) if (currentCat && Array.isArray(data)) { if (currentCat === '龙') { data = data.filter(p => p.category && (p.category.includes('龙') || p.category.includes('纪念钞'))) } else if (currentCat === '蛇') { data = data.filter(p => p.category && p.category.includes('蛇')) } else if (currentCat === '马') { data = data.filter(p => p.category && p.category.includes('马')) } else if (currentCat === '其他') { data = data.filter(p => p.category && !p.category.includes('龙') && !p.category.includes('纪念钞') && !p.category.includes('蛇') && !p.category.includes('马')) } } // 号码特色筛选(根据标题和内容关键字) if (numberFilter && Array.isArray(data)) { const filterKeywords = { '带4': ['带4', '带四', '通货', '标四'], '无4': ['无4', '无四', '带7'], '无47': ['无47', '无四七', '永恒'], '无247': ['无247', '无二四七', '天马', '金山'], '无347': ['无347', '无三四七', '钻石', '如意', '朦胧', '金马'], '年份': ['年份', '生日', '生日号', '纪念'], '特色': ['倒置', '圆圆', '豹子', '老虎', '狮子', '大象', '龙三', '龙二'] } const kw = filterKeywords[numberFilter] || [] if (kw.length > 0) { data = data.filter(p => { const text = (p.title || '') + (p.content || '') + (p.description || '') return kw.some(k => text.includes(k)) }) } } // 确保data是数组 if (!Array.isArray(data)) { data = data.posts || data.data || [] } console.log('YichensBoard: posts data count', data.length) if (currentCat && Array.isArray(data)) { if (currentCat === '龙') { data = data.filter(p => p.category && (p.category.includes('龙') || p.category.includes('纪念钞'))) } else if (currentCat === '蛇') { data = data.filter(p => p.category && p.category.includes('蛇')) } else if (currentCat === '马') { data = data.filter(p => p.category && p.category.includes('马')) } else if (currentCat === '其他') { data = data.filter(p => p.category && !p.category.includes('龙') && !p.category.includes('纪念钞') && !p.category.includes('蛇') && !p.category.includes('马')) } } // 支持新格式 {posts:[], total:xxx} 或旧格式 [{},{}] const postsArray = Array.isArray(data) ? data : (data.posts || []) const totalCount = data.total || todayStats.total || postsArray.length setPosts(postsArray) setTotalPosts(totalCount) } catch(e) { console.error('YichensBoard: fetchPosts error', e) setError(e.message) setPosts([]) } finally { setLoading(false) } } useEffect(() => { if (todayStats.total > 0) { fetchPosts(1, categoryFilter, searchKeyword) } }, [todayStats, categoryFilter, postTypeFilter, numberFilter]) useEffect(() => { setPage(1) fetchPosts(1, categoryFilter, searchKeyword) }, [searchKeyword, numberFilter]) const togglePost = id => setExpandedPosts(p => ({ ...p, [id]: !p[id] })) const StatCard = ({ label, value, color, onClick }) => (