// pages/statistics/statistics.ts import { todoStorage, ITodo, ITodoStats } from '../../utils/todoStorage'; Component({ data: { activeTab: 'statistics', stats: {} as ITodoStats, todos: [] as ITodo[], weeklyData: [] as any[], priorityData: [] as any[], categoryData: [] as any[], recentActivity: [] as any[] }, lifetimes: { attached() { this.loadData(); } }, pageLifetimes: { show() { this.loadData(); } }, methods: { // 加载数据 loadData() { const stats = todoStorage.getStats(); const todos = todoStorage.getAllTodos(); this.setData({ stats, todos }, () => { this.calculateWeeklyData(); this.calculatePriorityData(); this.calculateCategoryData(); this.calculateRecentActivity(); }); }, // 计算周数据 calculateWeeklyData() { const weekData = []; const today = new Date(); for (let i = 6; i >= 0; i--) { const date = new Date(today); date.setDate(date.getDate() - i); date.setHours(0, 0, 0, 0); const nextDate = new Date(date); nextDate.setDate(nextDate.getDate() + 1); const dayTodos = this.data.todos.filter(todo => { const todoDate = new Date(todo.createdAt); todoDate.setHours(0, 0, 0, 0); return todoDate.getTime() === date.getTime(); }); const completedTodos = dayTodos.filter(todo => todo.completed); weekData.push({ date: date.toLocaleDateString('zh-CN', { weekday: 'short' }), created: dayTodos.length, completed: completedTodos.length, dateObj: date }); } this.setData({ weeklyData: weekData }); }, // 计算优先级数据 calculatePriorityData() { const priorityCount = { high: 0, medium: 0, low: 0 }; const priorityCompleted = { high: 0, medium: 0, low: 0 }; this.data.todos.forEach(todo => { priorityCount[todo.priority]++; if (todo.completed) { priorityCompleted[todo.priority]++; } }); const priorityData = [ { name: '高优先级', total: priorityCount.high, completed: priorityCompleted.high, rate: priorityCount.high > 0 ? Math.round((priorityCompleted.high / priorityCount.high) * 100) : 0, color: '#ff6b6b' }, { name: '中优先级', total: priorityCount.medium, completed: priorityCompleted.medium, rate: priorityCount.medium > 0 ? Math.round((priorityCompleted.medium / priorityCount.medium) * 100) : 0, color: '#feca57' }, { name: '低优先级', total: priorityCount.low, completed: priorityCompleted.low, rate: priorityCount.low > 0 ? Math.round((priorityCompleted.low / priorityCount.low) * 100) : 0, color: '#48dbfb' } ]; this.setData({ priorityData }); }, // 计算分类数据 calculateCategoryData() { const categoryMap = new Map(); this.data.todos.forEach(todo => { const category = todo.category || '未分类'; if (!categoryMap.has(category)) { categoryMap.set(category, { total: 0, completed: 0 }); } categoryMap.get(category).total++; if (todo.completed) { categoryMap.get(category).completed++; } }); const categoryData = Array.from(categoryMap.entries()).map(([name, data]) => ({ name, total: data.total, completed: data.completed, rate: data.total > 0 ? Math.round((data.completed / data.total) * 100) : 0 })); this.setData({ categoryData }); }, // 计算最近活动 calculateRecentActivity() { const recentTodos = this.data.todos .sort((a, b) => b.createdAt - a.createdAt) .slice(0, 10); const recentActivity = recentTodos.map(todo => ({ id: todo.id, text: todo.text, completed: todo.completed, priority: todo.priority, createdAt: todo.createdAt, completedAt: todo.completedAt, timeAgo: this.getTimeAgo(todo.createdAt) })); this.setData({ recentActivity }); }, // 获取时间差 getTimeAgo(timestamp: number): string { const now = Date.now(); const diff = now - timestamp; const minutes = Math.floor(diff / (1000 * 60)); const hours = Math.floor(diff / (1000 * 60 * 60)); const days = Math.floor(diff / (1000 * 60 * 60 * 24)); if (minutes < 60) { return `${minutes}分钟前`; } else if (hours < 24) { return `${hours}小时前`; } else { return `${days}天前`; } }, // 标签页切换 onTabChange(e: any) { const targetPage = e.detail.value; if (targetPage === 'home') { wx.switchTab({ url: '/pages/index/index' }); } else if (targetPage === 'list') { wx.switchTab({ url: '/pages/list/list' }); } else if (targetPage === 'settings') { wx.switchTab({ url: '/pages/settings/settings' }); } }, // 导出数据 exportData() { const data = todoStorage.exportData(); wx.setClipboardData({ data: data, success: () => { wx.showToast({ title: '数据已复制到剪贴板', icon: 'success' }); } }); }, // 清空数据 clearData() { wx.showModal({ title: '确认清空', content: '确定要清空所有数据吗?此操作不可恢复!', success: (res) => { if (res.confirm) { todoStorage.clearAllData(); this.loadData(); wx.showToast({ title: '数据已清空', icon: 'success' }); } } }); }, // 获取优先级颜色 getPriorityColor(priority: string): string { switch (priority) { case 'high': return '#ff6b6b'; case 'medium': return '#feca57'; case 'low': return '#48dbfb'; default: return '#667eea'; } }, // 格式化百分比 formatPercentage(value: number): string { return `${value}%`; }, // 获取完成状态文本 getCompletionText(completed: boolean): string { return completed ? '已完成' : '进行中'; } } });