diff --git a/Makefile b/Makefile index 7f138f3..9634e53 100644 --- a/Makefile +++ b/Makefile @@ -39,6 +39,17 @@ install-obsidian: build-obsidian build-cli: cd $(GO_DIR) && $(GO_CMD) build -o $(HOME)/.local/bin/zhiyi-cli ./cmd/zhiyi-cli +# ─── Web UI ───────────────────────────────────────────── +build-web: + @echo "Web UI 使用静态 HTML(无需构建)" + @echo " - 前端入口: web-ui/index.html" + @echo " - 访问地址: http://localhost:7821/" + @echo " - API 地址: http://localhost:7821/api/v1/" + +# ─── 一键安装所有 ─────────────────────────────────────── +install-all: build-go build-cli install-obsidian + @echo "全部安装完成(重启服务: systemctl --user restart zhiyid)" + # ─── 测试 ──────────────────────────────────────────── test: diff --git a/go/internal/api/server.go b/go/internal/api/server.go index 41e7113..28add57 100644 --- a/go/internal/api/server.go +++ b/go/internal/api/server.go @@ -296,6 +296,11 @@ func NewServer() http.Handler { // ─── 路由注册 ────────────────────────────── + // ─── 静态文件服务(Web UI)───────────────────── + // webUIRoot 在函数顶部声明 + var webUIRoot string + // 后续在 catch-all 中处理(见文件末尾) + mux.HandleFunc("/health", routes.HandleHealth) // ─── Prometheus /metrics ───────────────────── mux.Handle("/metrics", metrics.Handler()) @@ -1052,16 +1057,38 @@ func NewServer() http.Handler { log.Println("[zhiyid] 多 Agent 架构 — Redis + FileGraph + EventBus + vLLM — 已启动") - // Catch-all: return JSON for unknown paths + // Web UI 静态文件根目录 + webUIRoot = os.Getenv("ZHIYI_WEB_UI_ROOT") + if webUIRoot == "" { + webUIRoot = "../web-ui" + } + + // Catch-all: 优先检查静态文件,再 JSON mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - if r.URL.Path == "/" || r.URL.Path == "" { + p := r.URL.Path + + // 静态文件服务(安全检查,不允许 .. 遍历) + if p != "/" && !strings.Contains(p, "..") { + filePath := webUIRoot + p + if _, err := os.Stat(filePath); err == nil { + http.ServeFile(w, r, filePath) + return + } + } + + // 根路径 → index.html + if p == "/" || p == "" { + if _, err := os.Stat(webUIRoot + "/index.html"); err == nil { + http.ServeFile(w, r, webUIRoot+"/index.html") + return + } respondJSON(w, 200, map[string]interface{}{ "service": "zhiyid", "status": "ok", "version": "0.1.0", }) return } respondJSON(w, 404, map[string]interface{}{ - "error": "endpoint not found: " + r.URL.Path, + "error": "endpoint not found: " + p, }) }) diff --git a/web-ui/index.html b/web-ui/index.html new file mode 100644 index 0000000..0c3de8a --- /dev/null +++ b/web-ui/index.html @@ -0,0 +1,464 @@ + + +
+ + +