428 lines
8.7 KiB
Go
428 lines
8.7 KiB
Go
/*
|
|
manager.go - 任务管理器
|
|
实现了任务的增删改查和业务逻辑
|
|
*/
|
|
|
|
package todo
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// Statistics 统计信息
|
|
type Statistics struct {
|
|
Total int `json:"total"` // 总任务数
|
|
Completed int `json:"completed"` // 已完成任务数
|
|
Pending int `json:"pending"` // 待完成任务数
|
|
CompletionRate float64 `json:"completion_rate"` // 完成率
|
|
ByPriority map[string]int `json:"by_priority"` // 按优先级统计
|
|
ByStatus map[string]int `json:"by_status"` // 按状态统计
|
|
AverageCompletionTime time.Duration `json:"average_completion_time"` // 平均完成时间
|
|
}
|
|
|
|
// Manager 任务管理器
|
|
type Manager struct {
|
|
tasks []Task
|
|
nextID int
|
|
storage Storage
|
|
}
|
|
|
|
// NewManager 创建新的任务管理器
|
|
func NewManager(dataFile string) (*Manager, error) {
|
|
storage, err := NewJSONStorage(dataFile)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("创建存储失败: %v", err)
|
|
}
|
|
|
|
return &Manager{
|
|
tasks: make([]Task, 0),
|
|
nextID: 1,
|
|
storage: storage,
|
|
}, nil
|
|
}
|
|
|
|
// Load 从存储加载任务
|
|
func (m *Manager) Load() error {
|
|
tasks, err := m.storage.Load()
|
|
if err != nil {
|
|
return fmt.Errorf("加载任务失败: %v", err)
|
|
}
|
|
|
|
m.tasks = tasks
|
|
|
|
// 更新下一个ID
|
|
maxID := 0
|
|
for _, task := range m.tasks {
|
|
if task.ID > maxID {
|
|
maxID = task.ID
|
|
}
|
|
}
|
|
m.nextID = maxID + 1
|
|
|
|
return nil
|
|
}
|
|
|
|
// Save 保存任务到存储
|
|
func (m *Manager) Save() error {
|
|
return m.storage.Save(m.tasks)
|
|
}
|
|
|
|
// AddTask 添加新任务
|
|
func (m *Manager) AddTask(content string) (*Task, error) {
|
|
content = strings.TrimSpace(content)
|
|
if content == "" {
|
|
return nil, fmt.Errorf("任务内容不能为空")
|
|
}
|
|
|
|
task := NewTask(m.nextID, content)
|
|
m.tasks = append(m.tasks, *task)
|
|
m.nextID++
|
|
|
|
return task, nil
|
|
}
|
|
|
|
// GetTasks 获取所有任务
|
|
func (m *Manager) GetTasks() []Task {
|
|
// 返回副本以防止外部修改
|
|
tasks := make([]Task, len(m.tasks))
|
|
copy(tasks, m.tasks)
|
|
|
|
// 排序任务
|
|
sort.Sort(TaskList(tasks))
|
|
|
|
return tasks
|
|
}
|
|
|
|
// GetTask 根据ID获取任务
|
|
func (m *Manager) GetTask(id int) (*Task, error) {
|
|
for i, task := range m.tasks {
|
|
if task.ID == id {
|
|
return &m.tasks[i], nil
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("任务不存在: ID %d", id)
|
|
}
|
|
|
|
// UpdateTask 更新任务内容
|
|
func (m *Manager) UpdateTask(id int, content string) (*Task, error) {
|
|
content = strings.TrimSpace(content)
|
|
if content == "" {
|
|
return nil, fmt.Errorf("任务内容不能为空")
|
|
}
|
|
|
|
task, err := m.GetTask(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
task.Update(content)
|
|
return task, nil
|
|
}
|
|
|
|
// CompleteTask 标记任务完成
|
|
func (m *Manager) CompleteTask(id int) (*Task, error) {
|
|
task, err := m.GetTask(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if task.Completed {
|
|
return nil, fmt.Errorf("任务已经完成")
|
|
}
|
|
|
|
task.Complete()
|
|
return task, nil
|
|
}
|
|
|
|
// UncompleteTask 标记任务未完成
|
|
func (m *Manager) UncompleteTask(id int) (*Task, error) {
|
|
task, err := m.GetTask(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if !task.Completed {
|
|
return nil, fmt.Errorf("任务尚未完成")
|
|
}
|
|
|
|
task.Uncomplete()
|
|
return task, nil
|
|
}
|
|
|
|
// DeleteTask 删除任务
|
|
func (m *Manager) DeleteTask(id int) (*Task, error) {
|
|
for i, task := range m.tasks {
|
|
if task.ID == id {
|
|
// 创建任务副本用于返回
|
|
deletedTask := task
|
|
|
|
// 从切片中删除任务
|
|
m.tasks = append(m.tasks[:i], m.tasks[i+1:]...)
|
|
|
|
return &deletedTask, nil
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("任务不存在: ID %d", id)
|
|
}
|
|
|
|
// SearchTasks 搜索任务
|
|
func (m *Manager) SearchTasks(keyword string) []Task {
|
|
keyword = strings.TrimSpace(keyword)
|
|
if keyword == "" {
|
|
return []Task{}
|
|
}
|
|
|
|
var results []Task
|
|
for _, task := range m.tasks {
|
|
if m.matchesKeyword(task, keyword) {
|
|
results = append(results, task)
|
|
}
|
|
}
|
|
|
|
// 排序结果
|
|
sort.Sort(TaskList(results))
|
|
|
|
return results
|
|
}
|
|
|
|
// matchesKeyword 检查任务是否匹配关键词
|
|
func (m *Manager) matchesKeyword(task Task, keyword string) bool {
|
|
keyword = strings.ToLower(keyword)
|
|
|
|
// 检查任务内容
|
|
if strings.Contains(strings.ToLower(task.Content), keyword) {
|
|
return true
|
|
}
|
|
|
|
// 检查任务描述
|
|
if strings.Contains(strings.ToLower(task.Description), keyword) {
|
|
return true
|
|
}
|
|
|
|
// 检查标签
|
|
for _, tag := range task.Tags {
|
|
if strings.Contains(strings.ToLower(tag), keyword) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// GetTasksByStatus 根据状态获取任务
|
|
func (m *Manager) GetTasksByStatus(completed bool) []Task {
|
|
var results []Task
|
|
for _, task := range m.tasks {
|
|
if task.Completed == completed {
|
|
results = append(results, task)
|
|
}
|
|
}
|
|
|
|
sort.Sort(TaskList(results))
|
|
return results
|
|
}
|
|
|
|
// GetTasksByPriority 根据优先级获取任务
|
|
func (m *Manager) GetTasksByPriority(priority Priority) []Task {
|
|
var results []Task
|
|
for _, task := range m.tasks {
|
|
if task.Priority == priority {
|
|
results = append(results, task)
|
|
}
|
|
}
|
|
|
|
sort.Sort(TaskList(results))
|
|
return results
|
|
}
|
|
|
|
// SetTaskPriority 设置任务优先级
|
|
func (m *Manager) SetTaskPriority(id int, priority Priority) (*Task, error) {
|
|
task, err := m.GetTask(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
task.SetPriority(priority)
|
|
return task, nil
|
|
}
|
|
|
|
// AddTaskTag 为任务添加标签
|
|
func (m *Manager) AddTaskTag(id int, tag string) (*Task, error) {
|
|
task, err := m.GetTask(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
task.AddTag(tag)
|
|
return task, nil
|
|
}
|
|
|
|
// RemoveTaskTag 移除任务标签
|
|
func (m *Manager) RemoveTaskTag(id int, tag string) (*Task, error) {
|
|
task, err := m.GetTask(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
task.RemoveTag(tag)
|
|
return task, nil
|
|
}
|
|
|
|
// SetTaskDescription 设置任务描述
|
|
func (m *Manager) SetTaskDescription(id int, description string) (*Task, error) {
|
|
task, err := m.GetTask(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
task.SetDescription(description)
|
|
return task, nil
|
|
}
|
|
|
|
// GetStatistics 获取统计信息
|
|
func (m *Manager) GetStatistics() Statistics {
|
|
stats := Statistics{
|
|
Total: len(m.tasks),
|
|
Completed: 0,
|
|
Pending: 0,
|
|
ByPriority: make(map[string]int),
|
|
ByStatus: make(map[string]int),
|
|
}
|
|
|
|
var totalCompletionTime time.Duration
|
|
completedCount := 0
|
|
|
|
for _, task := range m.tasks {
|
|
// 统计完成状态
|
|
if task.Completed {
|
|
stats.Completed++
|
|
if task.CompletedAt != nil {
|
|
totalCompletionTime += task.CompletionTime()
|
|
completedCount++
|
|
}
|
|
} else {
|
|
stats.Pending++
|
|
}
|
|
|
|
// 统计优先级
|
|
priorityStr := task.Priority.String()
|
|
stats.ByPriority[priorityStr]++
|
|
|
|
// 统计状态
|
|
if task.Completed {
|
|
stats.ByStatus["已完成"]++
|
|
} else {
|
|
stats.ByStatus["待完成"]++
|
|
}
|
|
}
|
|
|
|
// 计算完成率
|
|
if stats.Total > 0 {
|
|
stats.CompletionRate = float64(stats.Completed) / float64(stats.Total) * 100
|
|
}
|
|
|
|
// 计算平均完成时间
|
|
if completedCount > 0 {
|
|
stats.AverageCompletionTime = totalCompletionTime / time.Duration(completedCount)
|
|
}
|
|
|
|
return stats
|
|
}
|
|
|
|
// ClearCompleted 清除所有已完成的任务
|
|
func (m *Manager) ClearCompleted() int {
|
|
var remaining []Task
|
|
clearedCount := 0
|
|
|
|
for _, task := range m.tasks {
|
|
if task.Completed {
|
|
clearedCount++
|
|
} else {
|
|
remaining = append(remaining, task)
|
|
}
|
|
}
|
|
|
|
m.tasks = remaining
|
|
return clearedCount
|
|
}
|
|
|
|
// ClearAll 清除所有任务
|
|
func (m *Manager) ClearAll() int {
|
|
count := len(m.tasks)
|
|
m.tasks = make([]Task, 0)
|
|
m.nextID = 1
|
|
return count
|
|
}
|
|
|
|
// GetTaskCount 获取任务数量
|
|
func (m *Manager) GetTaskCount() int {
|
|
return len(m.tasks)
|
|
}
|
|
|
|
// GetCompletedCount 获取已完成任务数量
|
|
func (m *Manager) GetCompletedCount() int {
|
|
count := 0
|
|
for _, task := range m.tasks {
|
|
if task.Completed {
|
|
count++
|
|
}
|
|
}
|
|
return count
|
|
}
|
|
|
|
// GetPendingCount 获取待完成任务数量
|
|
func (m *Manager) GetPendingCount() int {
|
|
count := 0
|
|
for _, task := range m.tasks {
|
|
if !task.Completed {
|
|
count++
|
|
}
|
|
}
|
|
return count
|
|
}
|
|
|
|
// ValidateAllTasks 验证所有任务的有效性
|
|
func (m *Manager) ValidateAllTasks() []error {
|
|
var errors []error
|
|
for i, task := range m.tasks {
|
|
if err := task.Validate(); err != nil {
|
|
errors = append(errors, fmt.Errorf("任务 %d: %v", i, err))
|
|
}
|
|
}
|
|
return errors
|
|
}
|
|
|
|
// ExportTasks 导出任务(可以扩展为不同格式)
|
|
func (m *Manager) ExportTasks() []Task {
|
|
tasks := make([]Task, len(m.tasks))
|
|
copy(tasks, m.tasks)
|
|
return tasks
|
|
}
|
|
|
|
// ImportTasks 导入任务
|
|
func (m *Manager) ImportTasks(tasks []Task) error {
|
|
// 验证导入的任务
|
|
for i, task := range tasks {
|
|
if err := task.Validate(); err != nil {
|
|
return fmt.Errorf("导入任务 %d 验证失败: %v", i, err)
|
|
}
|
|
}
|
|
|
|
// 更新任务列表
|
|
m.tasks = append(m.tasks, tasks...)
|
|
|
|
// 更新下一个ID
|
|
maxID := m.nextID - 1
|
|
for _, task := range tasks {
|
|
if task.ID > maxID {
|
|
maxID = task.ID
|
|
}
|
|
}
|
|
m.nextID = maxID + 1
|
|
|
|
return nil
|
|
}
|