From 09c2a03cefa687832257d3b816da50db3cfcc0f2 Mon Sep 17 00:00:00 2001
From: ai_xiaopei <xiaopei@aisim.cn>
Date: Sat, 25 Jul 2026 23:48:11 +0800
Subject: [PATCH] feat: 实现输出格式化

---
 internal/output/formatter_test.go |   41 ++++++++++++++++++++
 internal/output/formatter.go      |   40 ++++++++++++++++++++
 2 files changed, 81 insertions(+), 0 deletions(-)

diff --git a/internal/output/formatter.go b/internal/output/formatter.go
new file mode 100644
index 0000000..91f7286
--- /dev/null
+++ b/internal/output/formatter.go
@@ -0,0 +1,40 @@
+package output
+
+import (
+	"encoding/json"
+	"fmt"
+	"strings"
+
+	"github.com/aisim/kb-cli/internal/search"
+)
+
+// FormatTable 表格格式输出
+func FormatTable(results []search.SearchResult) string {
+	if len(results) == 0 {
+		return "未找到匹配结果"
+	}
+
+	var sb strings.Builder
+	sb.WriteString(fmt.Sprintf("%-50s %-20s %-8s %s\n", "路径", "标题", "板块", "得分"))
+	sb.WriteString(strings.Repeat("-", 100) + "\n")
+
+	for _, r := range results {
+		title := r.Title
+		if len(title) > 18 {
+			title = title[:18] + ".."
+		}
+		sb.WriteString(fmt.Sprintf("%-50s %-20s %-8s %d\n", r.Path, title, r.Section, r.Score))
+	}
+
+	sb.WriteString(fmt.Sprintf("\n共 %d 条结果\n", len(results)))
+	return sb.String()
+}
+
+// FormatJSON JSON 格式输出
+func FormatJSON(results []search.SearchResult) (string, error) {
+	data, err := json.MarshalIndent(results, "", "  ")
+	if err != nil {
+		return "", err
+	}
+	return string(data), nil
+}
diff --git a/internal/output/formatter_test.go b/internal/output/formatter_test.go
new file mode 100644
index 0000000..d74544a
--- /dev/null
+++ b/internal/output/formatter_test.go
@@ -0,0 +1,41 @@
+package output
+
+import (
+	"strings"
+	"testing"
+
+	"github.com/aisim/kb-cli/internal/search"
+)
+
+func TestFormatTable(t *testing.T) {
+	results := []search.SearchResult{
+		{Path: "FAQ/充装类/001.md", Title: "充装问题", Section: "FAQ", Score: 100},
+	}
+	output := FormatTable(results)
+	if !strings.Contains(output, "FAQ") {
+		t.Error("output should contain section")
+	}
+	if !strings.Contains(output, "100") {
+		t.Error("output should contain score")
+	}
+}
+
+func TestFormatTableEmpty(t *testing.T) {
+	output := FormatTable(nil)
+	if output != "未找到匹配结果" {
+		t.Errorf("output = %q, want %q", output, "未找到匹配结果")
+	}
+}
+
+func TestFormatJSON(t *testing.T) {
+	results := []search.SearchResult{
+		{Path: "test.md", Title: "Test", Score: 50},
+	}
+	output, err := FormatJSON(results)
+	if err != nil {
+		t.Fatalf("FormatJSON failed: %v", err)
+	}
+	if !strings.Contains(output, "test.md") {
+		t.Error("JSON should contain path")
+	}
+}

--
Gitblit v1.9.1