完成
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()
|
||||
}
|
382
golang-learning/10-projects/02-todo-list/ui/colors.go
Normal file
382
golang-learning/10-projects/02-todo-list/ui/colors.go
Normal file
@@ -0,0 +1,382 @@
|
||||
/*
|
||||
colors.go - 颜色输出
|
||||
实现了命令行的彩色文本输出
|
||||
*/
|
||||
|
||||
package ui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Colors 颜色输出器
|
||||
type Colors struct {
|
||||
enabled bool
|
||||
}
|
||||
|
||||
// ANSI 颜色代码
|
||||
const (
|
||||
ColorReset = "\033[0m"
|
||||
ColorRed = "\033[31m"
|
||||
ColorGreen = "\033[32m"
|
||||
ColorYellow = "\033[33m"
|
||||
ColorBlue = "\033[34m"
|
||||
ColorMagenta = "\033[35m"
|
||||
ColorCyan = "\033[36m"
|
||||
ColorWhite = "\033[37m"
|
||||
ColorGray = "\033[90m"
|
||||
|
||||
// 背景色
|
||||
BgRed = "\033[41m"
|
||||
BgGreen = "\033[42m"
|
||||
BgYellow = "\033[43m"
|
||||
BgBlue = "\033[44m"
|
||||
BgMagenta = "\033[45m"
|
||||
BgCyan = "\033[46m"
|
||||
BgWhite = "\033[47m"
|
||||
|
||||
// 样式
|
||||
StyleBold = "\033[1m"
|
||||
StyleDim = "\033[2m"
|
||||
StyleItalic = "\033[3m"
|
||||
StyleUnderline = "\033[4m"
|
||||
StyleBlink = "\033[5m"
|
||||
StyleReverse = "\033[7m"
|
||||
StyleStrike = "\033[9m"
|
||||
)
|
||||
|
||||
// NewColors 创建新的颜色输出器
|
||||
func NewColors() *Colors {
|
||||
return &Colors{
|
||||
enabled: supportsColor(),
|
||||
}
|
||||
}
|
||||
|
||||
// supportsColor 检查终端是否支持颜色
|
||||
func supportsColor() bool {
|
||||
// Windows 命令提示符通常不支持 ANSI 颜色
|
||||
if runtime.GOOS == "windows" {
|
||||
// 检查是否在支持颜色的终端中运行
|
||||
term := os.Getenv("TERM")
|
||||
if term == "" {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查环境变量
|
||||
if os.Getenv("NO_COLOR") != "" {
|
||||
return false
|
||||
}
|
||||
|
||||
if os.Getenv("FORCE_COLOR") != "" {
|
||||
return true
|
||||
}
|
||||
|
||||
// 检查是否连接到终端
|
||||
if !isTerminal() {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// isTerminal 检查是否连接到终端
|
||||
func isTerminal() bool {
|
||||
// 简单检查:如果 stdout 是文件,可能不是终端
|
||||
stat, err := os.Stdout.Stat()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查是否是字符设备
|
||||
return (stat.Mode() & os.ModeCharDevice) != 0
|
||||
}
|
||||
|
||||
// colorize 为文本添加颜色
|
||||
func (c *Colors) colorize(text, color string) string {
|
||||
if !c.enabled {
|
||||
return text
|
||||
}
|
||||
return color + text + ColorReset
|
||||
}
|
||||
|
||||
// Red 红色文本
|
||||
func (c *Colors) Red(text string) string {
|
||||
return c.colorize(text, ColorRed)
|
||||
}
|
||||
|
||||
// Green 绿色文本
|
||||
func (c *Colors) Green(text string) string {
|
||||
return c.colorize(text, ColorGreen)
|
||||
}
|
||||
|
||||
// Yellow 黄色文本
|
||||
func (c *Colors) Yellow(text string) string {
|
||||
return c.colorize(text, ColorYellow)
|
||||
}
|
||||
|
||||
// Blue 蓝色文本
|
||||
func (c *Colors) Blue(text string) string {
|
||||
return c.colorize(text, ColorBlue)
|
||||
}
|
||||
|
||||
// Magenta 洋红色文本
|
||||
func (c *Colors) Magenta(text string) string {
|
||||
return c.colorize(text, ColorMagenta)
|
||||
}
|
||||
|
||||
// Cyan 青色文本
|
||||
func (c *Colors) Cyan(text string) string {
|
||||
return c.colorize(text, ColorCyan)
|
||||
}
|
||||
|
||||
// White 白色文本
|
||||
func (c *Colors) White(text string) string {
|
||||
return c.colorize(text, ColorWhite)
|
||||
}
|
||||
|
||||
// Gray 灰色文本
|
||||
func (c *Colors) Gray(text string) string {
|
||||
return c.colorize(text, ColorGray)
|
||||
}
|
||||
|
||||
// Bold 粗体文本
|
||||
func (c *Colors) Bold(text string) string {
|
||||
return c.colorize(text, StyleBold)
|
||||
}
|
||||
|
||||
// Dim 暗淡文本
|
||||
func (c *Colors) Dim(text string) string {
|
||||
return c.colorize(text, StyleDim)
|
||||
}
|
||||
|
||||
// Italic 斜体文本
|
||||
func (c *Colors) Italic(text string) string {
|
||||
return c.colorize(text, StyleItalic)
|
||||
}
|
||||
|
||||
// Underline 下划线文本
|
||||
func (c *Colors) Underline(text string) string {
|
||||
return c.colorize(text, StyleUnderline)
|
||||
}
|
||||
|
||||
// Blink 闪烁文本
|
||||
func (c *Colors) Blink(text string) string {
|
||||
return c.colorize(text, StyleBlink)
|
||||
}
|
||||
|
||||
// Reverse 反色文本
|
||||
func (c *Colors) Reverse(text string) string {
|
||||
return c.colorize(text, StyleReverse)
|
||||
}
|
||||
|
||||
// Strike 删除线文本
|
||||
func (c *Colors) Strike(text string) string {
|
||||
return c.colorize(text, StyleStrike)
|
||||
}
|
||||
|
||||
// BgRed 红色背景
|
||||
func (c *Colors) BgRedText(text string) string {
|
||||
return c.colorize(text, BgRed)
|
||||
}
|
||||
|
||||
// BgGreen 绿色背景
|
||||
func (c *Colors) BgGreenText(text string) string {
|
||||
return c.colorize(text, BgGreen)
|
||||
}
|
||||
|
||||
// BgYellow 黄色背景
|
||||
func (c *Colors) BgYellowText(text string) string {
|
||||
return c.colorize(text, BgYellow)
|
||||
}
|
||||
|
||||
// BgBlue 蓝色背景
|
||||
func (c *Colors) BgBlueText(text string) string {
|
||||
return c.colorize(text, BgBlue)
|
||||
}
|
||||
|
||||
// BgMagenta 洋红色背景
|
||||
func (c *Colors) BgMagentaText(text string) string {
|
||||
return c.colorize(text, BgMagenta)
|
||||
}
|
||||
|
||||
// BgCyan 青色背景
|
||||
func (c *Colors) BgCyanText(text string) string {
|
||||
return c.colorize(text, BgCyan)
|
||||
}
|
||||
|
||||
// BgWhite 白色背景
|
||||
func (c *Colors) BgWhiteText(text string) string {
|
||||
return c.colorize(text, BgWhite)
|
||||
}
|
||||
|
||||
// Combine 组合多种样式
|
||||
func (c *Colors) Combine(text string, styles ...string) string {
|
||||
if !c.enabled {
|
||||
return text
|
||||
}
|
||||
|
||||
var combined string
|
||||
for _, style := range styles {
|
||||
combined += style
|
||||
}
|
||||
|
||||
return combined + text + ColorReset
|
||||
}
|
||||
|
||||
// Success 成功样式(绿色粗体)
|
||||
func (c *Colors) Success(text string) string {
|
||||
return c.Combine(text, ColorGreen, StyleBold)
|
||||
}
|
||||
|
||||
// Error 错误样式(红色粗体)
|
||||
func (c *Colors) Error(text string) string {
|
||||
return c.Combine(text, ColorRed, StyleBold)
|
||||
}
|
||||
|
||||
// Warning 警告样式(黄色粗体)
|
||||
func (c *Colors) Warning(text string) string {
|
||||
return c.Combine(text, ColorYellow, StyleBold)
|
||||
}
|
||||
|
||||
// Info 信息样式(蓝色)
|
||||
func (c *Colors) Info(text string) string {
|
||||
return c.Blue(text)
|
||||
}
|
||||
|
||||
// Highlight 高亮样式(青色粗体)
|
||||
func (c *Colors) Highlight(text string) string {
|
||||
return c.Combine(text, ColorCyan, StyleBold)
|
||||
}
|
||||
|
||||
// Muted 静音样式(灰色暗淡)
|
||||
func (c *Colors) Muted(text string) string {
|
||||
return c.Combine(text, ColorGray, StyleDim)
|
||||
}
|
||||
|
||||
// Enable 启用颜色输出
|
||||
func (c *Colors) Enable() {
|
||||
c.enabled = true
|
||||
}
|
||||
|
||||
// Disable 禁用颜色输出
|
||||
func (c *Colors) Disable() {
|
||||
c.enabled = false
|
||||
}
|
||||
|
||||
// IsEnabled 检查颜色输出是否启用
|
||||
func (c *Colors) IsEnabled() bool {
|
||||
return c.enabled
|
||||
}
|
||||
|
||||
// Printf 带颜色的格式化输出
|
||||
func (c *Colors) Printf(color, format string, args ...interface{}) {
|
||||
text := fmt.Sprintf(format, args...)
|
||||
switch color {
|
||||
case "red":
|
||||
fmt.Print(c.Red(text))
|
||||
case "green":
|
||||
fmt.Print(c.Green(text))
|
||||
case "yellow":
|
||||
fmt.Print(c.Yellow(text))
|
||||
case "blue":
|
||||
fmt.Print(c.Blue(text))
|
||||
case "magenta":
|
||||
fmt.Print(c.Magenta(text))
|
||||
case "cyan":
|
||||
fmt.Print(c.Cyan(text))
|
||||
case "white":
|
||||
fmt.Print(c.White(text))
|
||||
case "gray":
|
||||
fmt.Print(c.Gray(text))
|
||||
default:
|
||||
fmt.Print(text)
|
||||
}
|
||||
}
|
||||
|
||||
// Println 带颜色的输出(带换行)
|
||||
func (c *Colors) Println(color, text string) {
|
||||
c.Printf(color, "%s\n", text)
|
||||
}
|
||||
|
||||
// Rainbow 彩虹文本(每个字符不同颜色)
|
||||
func (c *Colors) Rainbow(text string) string {
|
||||
if !c.enabled {
|
||||
return text
|
||||
}
|
||||
|
||||
colors := []string{ColorRed, ColorYellow, ColorGreen, ColorCyan, ColorBlue, ColorMagenta}
|
||||
var result string
|
||||
|
||||
for i, char := range text {
|
||||
color := colors[i%len(colors)]
|
||||
result += color + string(char) + ColorReset
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Gradient 渐变文本(从一种颜色到另一种颜色)
|
||||
func (c *Colors) Gradient(text, startColor, endColor string) string {
|
||||
if !c.enabled {
|
||||
return text
|
||||
}
|
||||
|
||||
// 简化实现:只在开头和结尾使用不同颜色
|
||||
if len(text) <= 2 {
|
||||
return c.colorize(text, startColor)
|
||||
}
|
||||
|
||||
mid := len(text) / 2
|
||||
return c.colorize(text[:mid], startColor) + c.colorize(text[mid:], endColor)
|
||||
}
|
||||
|
||||
// Table 表格样式输出
|
||||
func (c *Colors) Table(headers []string, rows [][]string) {
|
||||
// 计算列宽
|
||||
colWidths := make([]int, len(headers))
|
||||
for i, header := range headers {
|
||||
colWidths[i] = len(header)
|
||||
}
|
||||
|
||||
for _, row := range rows {
|
||||
for i, cell := range row {
|
||||
if i < len(colWidths) && len(cell) > colWidths[i] {
|
||||
colWidths[i] = len(cell)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 输出表头
|
||||
fmt.Print(c.Bold(c.Cyan("│")))
|
||||
for i, header := range headers {
|
||||
fmt.Printf(" %-*s ", colWidths[i], header)
|
||||
fmt.Print(c.Bold(c.Cyan("│")))
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
// 输出分隔线
|
||||
fmt.Print(c.Cyan("├"))
|
||||
for i, width := range colWidths {
|
||||
fmt.Print(c.Cyan(strings.Repeat("─", width+2)))
|
||||
if i < len(colWidths)-1 {
|
||||
fmt.Print(c.Cyan("┼"))
|
||||
}
|
||||
}
|
||||
fmt.Println(c.Cyan("┤"))
|
||||
|
||||
// 输出数据行
|
||||
for _, row := range rows {
|
||||
fmt.Print(c.Cyan("│"))
|
||||
for i, cell := range row {
|
||||
if i < len(colWidths) {
|
||||
fmt.Printf(" %-*s ", colWidths[i], cell)
|
||||
}
|
||||
fmt.Print(c.Cyan("│"))
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user