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