/* cli.go - 命令行界面 实现了彩色的命令行用户界面 */ package ui import ( "fmt" "os" "os/exec" "runtime" "strings" "../todo" ) // CLI 命令行界面 type CLI struct { colors *Colors } // NewCLI 创建新的命令行界面 func NewCLI() *CLI { return &CLI{ colors: NewColors(), } } // ShowWelcome 显示欢迎信息 func (c *CLI) ShowWelcome() { c.Clear() fmt.Println(c.colors.Cyan("=== 待办事项管理器 ===")) fmt.Println() fmt.Println("📝 一个简单而强大的待办事项管理工具") fmt.Println() c.ShowHelp() } // ShowHelp 显示帮助信息 func (c *CLI) ShowHelp() { fmt.Println(c.colors.Yellow("命令列表:")) fmt.Println(" " + c.colors.Green("add <任务>") + " - 添加新任务") fmt.Println(" " + c.colors.Green("list [状态]") + " - 显示任务列表 (all/done/pending)") fmt.Println(" " + c.colors.Green("done ") + " - 标记任务完成") fmt.Println(" " + c.colors.Green("delete ") + " - 删除任务") fmt.Println(" " + c.colors.Green("edit <新内容>") + " - 编辑任务") fmt.Println(" " + c.colors.Green("search <关键词>") + " - 搜索任务") fmt.Println(" " + c.colors.Green("stats") + " - 显示统计信息") fmt.Println(" " + c.colors.Green("clear") + " - 清屏") fmt.Println(" " + c.colors.Green("help") + " - 显示帮助") fmt.Println(" " + c.colors.Green("quit") + " - 退出程序") fmt.Println() } // ShowTaskList 显示任务列表 func (c *CLI) ShowTaskList(tasks []todo.Task) { if len(tasks) == 0 { c.ShowInfo("暂无任务") return } fmt.Println(c.colors.Cyan("📋 待办事项列表:")) for _, task := range tasks { c.showTask(task) } fmt.Println() } // showTask 显示单个任务 func (c *CLI) showTask(task todo.Task) { var status, statusColor string if task.Completed { status = "✅" statusColor = "green" } else { status = "⏳" statusColor = "yellow" } // 根据优先级选择颜色 var priorityColor string switch task.Priority { case todo.Urgent: priorityColor = "red" case todo.High: priorityColor = "magenta" case todo.Medium: priorityColor = "blue" case todo.Low: priorityColor = "cyan" default: priorityColor = "white" } // 格式化任务内容 content := task.Content if len(content) > 50 { content = content[:47] + "..." } // 显示任务 fmt.Printf(" [%s] %s %s %s\n", c.colors.Blue(fmt.Sprintf("%d", task.ID)), c.colorize(status, statusColor), c.colorize(content, "white"), c.colorize(fmt.Sprintf("(优先级: %s)", task.Priority), priorityColor)) // 显示标签 if len(task.Tags) > 0 { fmt.Printf(" %s %s\n", c.colors.Gray("标签:"), c.colors.Cyan(strings.Join(task.Tags, ", "))) } // 显示描述 if task.Description != "" { desc := task.Description if len(desc) > 60 { desc = desc[:57] + "..." } fmt.Printf(" %s %s\n", c.colors.Gray("描述:"), c.colors.White(desc)) } } // ShowStatistics 显示统计信息 func (c *CLI) ShowStatistics(stats todo.Statistics) { fmt.Println(c.colors.Cyan("📊 统计信息:")) fmt.Printf(" 总任务数: %s\n", c.colors.Blue(fmt.Sprintf("%d", stats.Total))) fmt.Printf(" 已完成: %s\n", c.colors.Green(fmt.Sprintf("%d", stats.Completed))) fmt.Printf(" 待完成: %s\n", c.colors.Yellow(fmt.Sprintf("%d", stats.Pending))) fmt.Printf(" 完成率: %s\n", c.colors.Magenta(fmt.Sprintf("%.1f%%", stats.CompletionRate))) if len(stats.ByPriority) > 0 { fmt.Println() fmt.Println(c.colors.Yellow("按优先级统计:")) for priority, count := range stats.ByPriority { var color string switch priority { case "紧急": color = "red" case "高": color = "magenta" case "中": color = "blue" case "低": color = "cyan" default: color = "white" } fmt.Printf(" %s: %s\n", c.colorize(priority, color), c.colors.White(fmt.Sprintf("%d", count))) } } if stats.AverageCompletionTime > 0 { fmt.Printf("\n 平均完成时间: %s\n", c.colors.Cyan(stats.AverageCompletionTime.String())) } fmt.Println() } // ShowSuccess 显示成功消息 func (c *CLI) ShowSuccess(message string) { fmt.Printf("%s %s\n", c.colors.Green("✅"), message) } // ShowError 显示错误消息 func (c *CLI) ShowError(message string) { fmt.Printf("%s %s\n", c.colors.Red("❌"), c.colors.Red(message)) } // ShowWarning 显示警告消息 func (c *CLI) ShowWarning(message string) { fmt.Printf("%s %s\n", c.colors.Yellow("⚠️"), c.colors.Yellow(message)) } // ShowInfo 显示信息消息 func (c *CLI) ShowInfo(message string) { fmt.Printf("%s %s\n", c.colors.Blue("ℹ️"), message) } // Clear 清屏 func (c *CLI) Clear() { var cmd *exec.Cmd switch runtime.GOOS { case "windows": cmd = exec.Command("cmd", "/c", "cls") default: cmd = exec.Command("clear") } cmd.Stdout = os.Stdout cmd.Run() } // colorize 根据颜色名称着色文本 func (c *CLI) colorize(text, color string) string { switch strings.ToLower(color) { case "red": return c.colors.Red(text) case "green": return c.colors.Green(text) case "yellow": return c.colors.Yellow(text) case "blue": return c.colors.Blue(text) case "magenta": return c.colors.Magenta(text) case "cyan": return c.colors.Cyan(text) case "white": return c.colors.White(text) case "gray": return c.colors.Gray(text) default: return text } } // ShowTaskDetail 显示任务详细信息 func (c *CLI) ShowTaskDetail(task todo.Task) { fmt.Println(c.colors.Cyan("📋 任务详情:")) fmt.Println(c.colors.Gray("─────────────────────────────────────")) fmt.Printf("ID: %s\n", c.colors.Blue(fmt.Sprintf("%d", task.ID))) fmt.Printf("内容: %s\n", c.colors.White(task.Content)) if task.Completed { fmt.Printf("状态: %s\n", c.colors.Green("✅ 已完成")) } else { fmt.Printf("状态: %s\n", c.colors.Yellow("⏳ 待完成")) } var priorityColor string switch task.Priority { case todo.Urgent: priorityColor = "red" case todo.High: priorityColor = "magenta" case todo.Medium: priorityColor = "blue" case todo.Low: priorityColor = "cyan" } fmt.Printf("优先级: %s\n", c.colorize(task.Priority.String(), priorityColor)) fmt.Printf("创建时间: %s\n", c.colors.Gray(task.CreatedAt.Format("2006-01-02 15:04:05"))) fmt.Printf("更新时间: %s\n", c.colors.Gray(task.UpdatedAt.Format("2006-01-02 15:04:05"))) if task.Completed && task.CompletedAt != nil { fmt.Printf("完成时间: %s\n", c.colors.Green(task.CompletedAt.Format("2006-01-02 15:04:05"))) fmt.Printf("完成耗时: %s\n", c.colors.Cyan(task.CompletionTime().String())) } if task.Description != "" { fmt.Printf("描述: %s\n", c.colors.White(task.Description)) } if len(task.Tags) > 0 { fmt.Printf("标签: %s\n", c.colors.Cyan(strings.Join(task.Tags, ", "))) } fmt.Println(c.colors.Gray("─────────────────────────────────────")) fmt.Println() } // ShowProgress 显示进度条 func (c *CLI) ShowProgress(current, total int, label string) { if total == 0 { return } percentage := float64(current) / float64(total) * 100 barLength := 30 filledLength := int(float64(barLength) * float64(current) / float64(total)) bar := strings.Repeat("█", filledLength) + strings.Repeat("░", barLength-filledLength) fmt.Printf("\r%s [%s] %.1f%% (%d/%d)", label, c.colors.Green(bar), percentage, current, total) } // ConfirmAction 确认操作 func (c *CLI) ConfirmAction(message string) bool { fmt.Printf("%s %s (y/N): ", c.colors.Yellow("❓"), message) var response string fmt.Scanln(&response) response = strings.ToLower(strings.TrimSpace(response)) return response == "y" || response == "yes" } // ShowBanner 显示横幅 func (c *CLI) ShowBanner(text string) { length := len(text) + 4 border := strings.Repeat("=", length) fmt.Println(c.colors.Cyan(border)) fmt.Printf("%s %s %s\n", c.colors.Cyan("="), c.colors.White(text), c.colors.Cyan("=")) fmt.Println(c.colors.Cyan(border)) fmt.Println() }