// pages/list/list.ts import { todoStorage, ITodo, ITodoStats } from '../../utils/todoStorage'; Component({ data: { activeTab: 'list', todos: [] as ITodo[], filteredTodos: [] as ITodo[], stats: {} as ITodoStats, searchText: '', filterStatus: 'all' as 'all' | 'pending' | 'completed', filterPriority: 'all' as 'all' | 'high' | 'medium' | 'low', sortBy: 'createdAt' as 'createdAt' | 'priority' | 'text', pendingCount: 0, completedCount: 0, completionRate: 0, showAddSheet: false, showDateTimePicker: false, newTodoText: '', newTodoPriority: 'medium' as 'high' | 'medium' | 'low', newTodoCategory: '', newTodoDeadline: 0, newTodoNote: '', dateTimeRange: [ [], // 年月日 [] // 时分 ] as string[][], dateTimeValue: [0, 0] as number[] }, lifetimes: { attached() { this.loadData(); } }, pageLifetimes: { show() { this.loadData(); } }, methods: { // 加载数据 loadData() { const todos = todoStorage.getAllTodos(); const stats = todoStorage.getStats(); this.setData({ todos, stats }); this.applyFilters(); }, // 筛选和排序任务 applyFilters() { let filtered = [...this.data.todos]; // 搜索筛选 if (this.data.searchText) { filtered = filtered.filter(todo => todo.text.toLowerCase().includes(this.data.searchText.toLowerCase()) ); } // 状态筛选 if (this.data.filterStatus === 'pending') { filtered = filtered.filter(todo => !todo.completed); } else if (this.data.filterStatus === 'completed') { filtered = filtered.filter(todo => todo.completed); } // 优先级筛选 if (this.data.filterPriority !== 'all') { filtered = filtered.filter(todo => todo.priority === this.data.filterPriority); } // 排序 filtered.sort((a, b) => { switch (this.data.sortBy) { case 'createdAt': return b.createdAt - a.createdAt; case 'priority': { const priorityOrder = { high: 3, medium: 2, low: 1 }; return priorityOrder[b.priority] - priorityOrder[a.priority]; } case 'text': return a.text.localeCompare(b.text); default: return 0; } }); // 计算统计数据 const pendingCount = filtered.filter(todo => !todo.completed).length; const completedCount = filtered.filter(todo => todo.completed).length; const completionRate = filtered.length > 0 ? Math.round((completedCount / filtered.length) * 100) : 0; this.setData({ filteredTodos: filtered, pendingCount, completedCount, completionRate }); }, // 搜索输入 onSearchInput(e: any) { this.setData({ searchText: e.detail.value }, () => { this.applyFilters(); }); }, // 状态筛选 onStatusFilterChange(e: any) { this.setData({ filterStatus: e.currentTarget.dataset.value }, () => { this.applyFilters(); }); }, // 优先级筛选 onPriorityFilterChange(e: any) { this.setData({ filterPriority: e.currentTarget.dataset.value }, () => { this.applyFilters(); }); }, // 排序 onSortChange(e: any) { this.setData({ sortBy: e.currentTarget.dataset.value }, () => { this.applyFilters(); }); }, // 显示添加半屏 showAddSheet() { this.initDateTimeRange(); this.setData({ showAddSheet: true, newTodoText: '', newTodoPriority: 'medium', newTodoCategory: '', newTodoDeadline: 0, newTodoNote: '' }); }, // 隐藏添加半屏 hideAddSheet() { this.setData({ showAddSheet: false }); }, // 阻止事件冒泡 stopPropagation() { // 空函数,用于阻止事件冒泡 }, // 输入新任务 onNewTodoInput(e: any) { this.setData({ newTodoText: e.detail.value }); }, // 输入备注 onNewTodoNoteInput(e: any) { this.setData({ newTodoNote: e.detail.value }); }, // 设置优先级 onPriorityChange(e: any) { this.setData({ newTodoPriority: e.currentTarget.dataset.value }); }, // 设置分类 onCategoryChange(e: any) { this.setData({ newTodoCategory: e.currentTarget.dataset.value }); }, // 初始化日期时间选择器 initDateTimeRange() { const now = new Date(); const year = now.getFullYear(); const month = now.getMonth(); const date = now.getDate(); // 生成日期选项(今天及之后30天) const dateOptions = []; for (let i = 0; i < 30; i++) { const d = new Date(year, month, date + i); const dateStr = this.formatDateOption(d); dateOptions.push(dateStr); } // 生成时间选项 const timeOptions = []; for (let h = 0; h < 24; h++) { for (let m = 0; m < 60; m += 30) { const timeStr = `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}`; timeOptions.push(timeStr); } } this.setData({ dateTimeRange: [dateOptions, timeOptions], dateTimeValue: [0, 16] // 默认选择今天 08:00 }); }, // 格式化日期选项 formatDateOption(date: Date): string { const now = new Date(); const today = new Date(now.getFullYear(), now.getMonth(), now.getDate()); const tomorrow = new Date(today.getTime() + 24 * 60 * 60 * 1000); if (date.getTime() === today.getTime()) { return '今天'; } else if (date.getTime() === tomorrow.getTime()) { return '明天'; } else { return `${date.getMonth() + 1}月${date.getDate()}日`; } }, // 显示日期时间选择器 showDateTimePicker() { // 先触发选择器 const that = this; wx.showActionSheet({ itemList: ['今天', '明天', '后天', '自定义日期'], success(res) { const now = new Date(); let selectedDate = new Date(); switch(res.tapIndex) { case 0: // 今天 selectedDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 18, 0); break; case 1: // 明天 selectedDate = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 18, 0); break; case 2: // 后天 selectedDate = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 2, 18, 0); break; case 3: // 自定义 that.showCustomDatePicker(); return; } that.setData({ newTodoDeadline: selectedDate.getTime() }); } }); }, // 显示自定义日期选择器 showCustomDatePicker() { const now = new Date(); const currentDate = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')}`; const currentTime = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`; wx.showModal({ title: '选择截止时间', content: '请在系统设置中选择日期和时间', showCancel: true, cancelText: '取消', confirmText: '使用当前时间', success: (res) => { if (res.confirm) { // 使用当前时间加1小时作为默认截止时间 const deadline = new Date(); deadline.setHours(deadline.getHours() + 1); this.setData({ newTodoDeadline: deadline.getTime() }); } } }); }, // 清除截止时间 clearDeadline() { this.setData({ newTodoDeadline: 0 }); }, // 隐藏日期时间选择器 hideDateTimePicker() { this.setData({ showDateTimePicker: false }); }, // 日期时间选择器改变 onDateTimeChange(e: any) { const [dateIndex, timeIndex] = e.detail.value; const { dateTimeRange } = this.data; // 计算选择的日期时间 const now = new Date(); const selectedDate = new Date(now.getFullYear(), now.getMonth(), now.getDate() + dateIndex); const timeStr = dateTimeRange[1][timeIndex]; const [hours, minutes] = timeStr.split(':').map(Number); selectedDate.setHours(hours, minutes, 0, 0); this.setData({ dateTimeValue: [dateIndex, timeIndex], newTodoDeadline: selectedDate.getTime(), showDateTimePicker: false }); }, // 格式化日期时间显示 formatDateTime(timestamp: number): string { const date = new Date(timestamp); const now = new Date(); const today = new Date(now.getFullYear(), now.getMonth(), now.getDate()); const tomorrow = new Date(today.getTime() + 24 * 60 * 60 * 1000); let dateStr = ''; if (date.toDateString() === today.toDateString()) { dateStr = '今天'; } else if (date.toDateString() === tomorrow.toDateString()) { dateStr = '明天'; } else { dateStr = `${date.getMonth() + 1}月${date.getDate()}日`; } const timeStr = `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`; return `${dateStr} ${timeStr}`; }, // 添加新任务 addTodo() { const { newTodoText, newTodoPriority, newTodoCategory, newTodoDeadline, newTodoNote } = this.data; if (newTodoText.trim() === '') { wx.showToast({ title: '请输入任务内容', icon: 'none' }); return; } todoStorage.addTodo( newTodoText.trim(), newTodoPriority, newTodoCategory || undefined, newTodoDeadline || undefined, newTodoNote.trim() || undefined ); this.hideAddSheet(); this.loadData(); wx.showToast({ title: '任务已添加', icon: 'success' }); }, // 切换任务状态 toggleTodo(e: any) { const id = e.currentTarget.dataset.id; todoStorage.toggleTodo(id); this.loadData(); }, // 编辑任务 editTodo(e: any) { const id = e.currentTarget.dataset.id; const todo = this.data.todos.find(t => t.id === id); if (todo) { wx.showModal({ title: '编辑任务', content: '编辑功能开发中,敬请期待!', showCancel: false }); } }, // 删除任务 deleteTodo(e: any) { const id = e.currentTarget.dataset.id; wx.showModal({ title: '确认删除', content: '确定要删除这个任务吗?', success: (res) => { if (res.confirm) { todoStorage.deleteTodo(id); this.loadData(); wx.showToast({ title: '已删除', icon: 'success' }); } } }); }, // 清空已完成任务 clearCompleted() { wx.showModal({ title: '确认清空', content: '确定要清空所有已完成的任务吗?此操作不可恢复。', success: (res) => { if (res.confirm) { const todos = this.data.todos.filter(todo => !todo.completed); todoStorage.saveAllTodos(todos); this.loadData(); wx.showToast({ title: '已清空', icon: 'success' }); } } }); }, // 导出数据 exportData() { const data = todoStorage.exportData(); wx.setClipboardData({ data: data, success: () => { wx.showToast({ title: '数据已复制到剪贴板', icon: 'success' }); } }); }, // 格式化时间 formatTime(timestamp: number): string { const date = new Date(timestamp); const now = new Date(); const diff = now.getTime() - date.getTime(); const days = Math.floor(diff / (1000 * 60 * 60 * 24)); if (days === 0) { return '今天'; } else if (days === 1) { return '昨天'; } else if (days < 7) { return `${days}天前`; } else { return date.toLocaleDateString(); } }, // 标签页切换 onTabChange(e: any) { const targetPage = e.detail.value; if (targetPage === 'home') { wx.switchTab({ url: '/pages/index/index' }); } else if (targetPage === 'statistics') { wx.switchTab({ url: '/pages/statistics/statistics' }); } else if (targetPage === 'settings') { wx.switchTab({ url: '/pages/settings/settings' }); } } } });