316 lines
8.0 KiB
Go
316 lines
8.0 KiB
Go
/*
|
||
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()
|
||
}
|