完成
This commit is contained in:
427
golang-learning/10-projects/02-todo-list/todo/manager.go
Normal file
427
golang-learning/10-projects/02-todo-list/todo/manager.go
Normal file
@@ -0,0 +1,427 @@
|
||||
/*
|
||||
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
|
||||
}
|
Reference in New Issue
Block a user