396 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// pages/index/index.ts
import { todoStorage, ITodo, ITodoStats } from '../../utils/todoStorage';
Component({
data: {
activeTab: 'home',
stats: {} as ITodoStats,
todayTodos: [] as ITodo[],
recentTodos: [] as ITodo[],
greeting: '',
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();
this.setGreeting();
}
},
pageLifetimes: {
show() {
this.loadData();
}
},
methods: {
// 加载数据
loadData() {
const stats = todoStorage.getStats();
const todayTodos = todoStorage.getTodayTodos();
const allTodos = todoStorage.getAllTodos();
const recentTodos = allTodos.slice(0, 5);
this.setData({
stats,
todayTodos,
recentTodos
});
},
// 获取成就图标
getAchievementIcon(completionRate: number): string {
if (completionRate === 100) return 'star-filled';
if (completionRate >= 80) return 'medal';
if (completionRate >= 60) return 'thumb-up';
if (completionRate >= 40) return 'check-circle';
if (completionRate >= 20) return 'time';
return 'hourglass';
},
// 获取成就颜色
getAchievementColor(completionRate: number): string {
if (completionRate === 100) return '#ffd700';
if (completionRate >= 80) return '#00a870';
if (completionRate >= 60) return '#0052d9';
if (completionRate >= 40) return '#ed7b2f';
if (completionRate >= 20) return '#666';
return '#999';
},
// 获取成就文本
getAchievementText(completionRate: number): string {
if (completionRate === 100) return '完美完成!';
if (completionRate >= 80) return '表现优秀';
if (completionRate >= 60) return '进展良好';
if (completionRate >= 40) return '稳步前进';
if (completionRate >= 20) return '开始行动';
return '加油冲刺';
},
// 设置问候语
setGreeting() {
const hour = new Date().getHours();
let greeting = '';
if (hour < 6) {
greeting = '夜深了,注意休息';
} else if (hour < 12) {
greeting = '早上好!新的一天开始了';
} else if (hour < 18) {
greeting = '下午好!继续加油';
} else {
greeting = '晚上好!今天过得怎么样';
}
this.setData({ greeting });
},
// 标签页切换
onTabChange(e: any) {
const targetPage = e.detail.value;
if (targetPage === 'list') {
wx.switchTab({ url: '/pages/list/list' });
} else if (targetPage === 'statistics') {
wx.switchTab({ url: '/pages/statistics/statistics' });
} else if (targetPage === 'settings') {
wx.switchTab({ url: '/pages/settings/settings' });
}
},
// 快速操作
goToTasks() {
wx.switchTab({ url: '/pages/list/list' });
},
goToStatistics() {
wx.switchTab({ url: '/pages/statistics/statistics' });
},
goToSettings() {
wx.switchTab({ url: '/pages/settings/settings' });
},
// 显示添加半屏
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();
},
// 删除任务
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'
});
}
}
});
},
// 格式化时间
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();
}
}
}
});