Files
golang/golang-learning/10-projects/02-todo-list/ui/cli.go
2025-08-24 13:01:09 +08:00

316 lines
8.0 KiB
Go
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

/*
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 <ID>") + " - 标记任务完成")
fmt.Println(" " + c.colors.Green("delete <ID>") + " - 删除任务")
fmt.Println(" " + c.colors.Green("edit <ID> <新内容>") + " - 编辑任务")
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()
}