237 lines
6.4 KiB
TypeScript

// 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 ? '已完成' : '进行中';
}
}
});