diff --git a/server/cmd/api/main.go b/server/cmd/api/main.go index c271e66..bd60df7 100644 --- a/server/cmd/api/main.go +++ b/server/cmd/api/main.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "encoding/json" "io" "log" "os" @@ -15,6 +16,8 @@ import ( "x-agents/server/internal/service" "github.com/gin-gonic/gin" + swaggerFiles "github.com/swaggo/files" + ginSwagger "github.com/swaggo/gin-swagger" ) // Logger 日志记录器 @@ -56,6 +59,83 @@ func (l *Logger) LogRequest(method, path, body string, status int, duration time var logger *Logger +// initDefaultAdmin 初始化默认管理员用户 +func initDefaultAdmin(userRepo *repository.UserRepository) { + // 确保 admin 用户的工作空间目录存在 + ensureAdminWorkspace() + + // 检查 admin 用户是否已存在 + _, err := userRepo.FindByUsername("admin") + if err == nil { + log.Println("Admin user already exists") + return + } + + // 使用 AuthService 创建用户(会自动加密密码) + authService := service.NewAuthService("", userRepo) + adminUser, err := authService.Register("admin", "admin", "admin@example.com") + if err != nil { + log.Printf("Failed to create admin user: %v", err) + return + } + + // 更新角色为管理员 + adminUser.RoleID = "admin" + userRepo.Update(adminUser) + + // 创建管理员角色 + perms, _ := json.Marshal([]int{int(model.PermissionRead), int(model.PermissionWrite), int(model.PermissionExecute), int(model.PermissionAdmin)}) + adminRole := &model.Role{ + ID: "admin", + Name: "admin", + Permissions: string(perms), + } + userRepo.CreateRole(adminRole) + + log.Printf("Default admin user created: id=%s, username=admin", adminUser.ID) +} + +// ensureAdminWorkspace 确保 admin 用户工作空间目录存在 +func ensureAdminWorkspace() { + execPath, _ := os.Getwd() + projectRoot := execPath + + // 如果当前目录名为 server,向上找一级 + baseName := filepath.Base(execPath) + if baseName == "server" { + projectRoot = filepath.Dir(execPath) + } + + // 尝试向上查找包含 .git 的目录 + if _, err := os.Stat(filepath.Join(projectRoot, ".git")); os.IsNotExist(err) { + for i := 0; i < 3; i++ { + parent := filepath.Dir(projectRoot) + if parent == projectRoot { + break + } + if _, err := os.Stat(filepath.Join(parent, ".git")); err == nil { + projectRoot = parent + break + } + projectRoot = parent + } + } + + // 创建 admin 工作空间 + workspacePath := filepath.Join(projectRoot, "account", "admin") + if err := os.MkdirAll(workspacePath, 0755); err != nil { + log.Printf("Warning: failed to create admin workspace: %v", err) + return + } + + // 创建子目录 + for _, dir := range []string{"projects", "files", "temp"} { + os.MkdirAll(filepath.Join(workspacePath, dir), 0755) + } + + log.Printf("Admin workspace created at: %s", workspacePath) +} + func main() { // 初始化日志 logger = NewLogger() @@ -71,7 +151,66 @@ func main() { } // 3. 自动迁移表 - db.AutoMigrate(&model.DatabaseInfo{}, &model.SubTableInfo{}, &model.ModelInfo{}, &model.KnowledgeBase{}, &model.KnowledgeDocument{}, &model.User{}, &model.Role{}) + db.AutoMigrate(&model.DatabaseInfo{}, &model.SubTableInfo{}, &model.ModelInfo{}, &model.KnowledgeBase{}, &model.KnowledgeDocument{}, &model.User{}, &model.Role{}, &model.Tool{}) + + // 3.1 确保 users 和 roles 表存在(使用 SQL 强制创建) + db.Exec(` + CREATE TABLE IF NOT EXISTS roles ( + id VARCHAR(191) PRIMARY KEY, + name VARCHAR(191) UNIQUE, + permissions TEXT, + created_at DATETIME(3), + updated_at DATETIME(3) + ) + `) + db.Exec(` + CREATE TABLE IF NOT EXISTS users ( + id VARCHAR(191) PRIMARY KEY, + username VARCHAR(50) UNIQUE NOT NULL, + password VARCHAR(191) NOT NULL, + email VARCHAR(191), + role_id VARCHAR(50) NOT NULL, + is_active BOOLEAN DEFAULT TRUE, + created_at DATETIME(3), + updated_at DATETIME(3), + INDEX idx_users_username (username), + INDEX idx_users_email (email) + ) + `) + + // 3.2 确保 tools 表存在(使用 SQL 强制创建) + db.Exec(` + CREATE TABLE IF NOT EXISTS tools ( + id VARCHAR(191) PRIMARY KEY, + name VARCHAR(100) UNIQUE NOT NULL, + description TEXT, + category VARCHAR(50) NOT NULL, + provider VARCHAR(100), + security_level VARCHAR(20) DEFAULT 'safe', + require_approval BOOLEAN DEFAULT FALSE, + parameters TEXT, + status VARCHAR(20) DEFAULT 'active', + created_at DATETIME(3), + updated_at DATETIME(3), + INDEX idx_tools_name (name), + INDEX idx_tools_category (category), + INDEX idx_tools_status (status) + ) + `) + + // 使用GORM Migrator添加缺失的列 + migrator := db.Migrator() + if !migrator.HasColumn(&model.Tool{}, "security_level") { + migrator.AddColumn(&model.Tool{}, "security_level") + } + if !migrator.HasColumn(&model.Tool{}, "require_approval") { + migrator.AddColumn(&model.Tool{}, "require_approval") + } + if !migrator.HasColumn(&model.Tool{}, "parameters") { + migrator.AddColumn(&model.Tool{}, "parameters") + } + + log.Println("Database tables verified/created") // 4. 初始化 Repository dbRepo := repository.NewDatabaseRepository(db) @@ -79,6 +218,10 @@ func main() { modelRepo := repository.NewModelRepository(db) knowledgeRepo := repository.NewKnowledgeRepository(db) userRepo := repository.NewUserRepository(db) + toolRepo := repository.NewToolRepository(db) + + // 4.1 初始化默认管理员用户 + initDefaultAdmin(userRepo) // 5. 初始化 Service dbService := service.NewDatabaseService(dbRepo, subTableRepo) @@ -91,6 +234,14 @@ func main() { } knowledgeService := service.NewKnowledgeService(knowledgeRepo, modelRepo, uploadService, cfg.PythonServiceURL, cfg.AICoreServiceAddr, cfg.MarkdownLocalPath) authService := service.NewAuthService(cfg.JWTSecret, userRepo) + toolService := service.NewToolService(toolRepo) + + // 4.2 初始化默认工具 + if err := toolService.InitDefaultTools(); err != nil { + log.Printf("Warning: Failed to init default tools: %v", err) + } else { + log.Println("Default tools initialized") + } // 6. 初始化 Handler dbHandler := handler.NewDatabaseHandler(dbService) @@ -100,6 +251,7 @@ func main() { systemHandler := handler.NewSystemHandler() knowledgeHandler := handler.NewKnowledgeHandler(knowledgeService) authHandler := handler.NewAuthHandler(authService) + toolHandler := handler.NewToolHandler(toolService) var uploadHandler *handler.UploadHandler if uploadService != nil { uploadHandler = handler.NewUploadHandler(uploadService, knowledgeRepo) @@ -137,8 +289,8 @@ func main() { // CORS 中间件 r.Use(func(c *gin.Context) { c.Writer.Header().Set("Access-Control-Allow-Origin", "*") - c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") - c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") + c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH") + c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With") if c.Request.Method == "OPTIONS" { c.AbortWithStatus(204) @@ -162,6 +314,14 @@ func main() { authProtectedGroup.GET("/me", authHandler.GetCurrentUser) } + // 用户管理模块(需要登录) + userGroup := r.Group("/user") + userGroup.Use(middleware.Auth(cfg.JWTSecret)) + { + userGroup.GET("/list", authHandler.ListUsers) + userGroup.GET("/:id", authHandler.GetUserByID) + } + // 数据库管理模块 databaseGroup := r.Group("/database") { @@ -225,6 +385,20 @@ func main() { // 系统信息模块 r.GET("/system/info", systemHandler.GetSystemInfo) + // 工具管理模块 + toolGroup := r.Group("/tool") + { + toolGroup.GET("/list", toolHandler.List) + toolGroup.GET("/sync", toolHandler.Sync) // 手动同步 + toolGroup.GET("/:id", toolHandler.GetByID) + toolGroup.POST("/add", toolHandler.Create) + toolGroup.PUT("/:id", toolHandler.Update) + toolGroup.DELETE("/:id", toolHandler.Delete) + } + + // Swagger 文档 + r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) + // 文件上传模块 if uploadHandler != nil { // 本地文件静态服务 diff --git a/server/docs/docs.go b/server/docs/docs.go new file mode 100644 index 0000000..9d11be1 --- /dev/null +++ b/server/docs/docs.go @@ -0,0 +1,2936 @@ +// Package docs Code generated by swaggo/swag. DO NOT EDIT +package docs + +import "github.com/swaggo/swag" + +const docTemplate = `{ + "schemes": {{ marshal .Schemes }}, + "swagger": "2.0", + "info": { + "description": "{{escape .Description}}", + "title": "{{.Title}}", + "contact": {}, + "version": "{{.Version}}" + }, + "host": "{{.Host}}", + "basePath": "{{.BasePath}}", + "paths": { + "/api/file_proxy": { + "get": { + "description": "代理访问文件,解决 MinIO 内网和 HTTPS 问题", + "consumes": [ + "application/json" + ], + "produces": [ + "application/octet-stream" + ], + "tags": [ + "文件上传" + ], + "summary": "代理文件访问", + "parameters": [ + { + "type": "string", + "description": "文件Key", + "name": "key", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "知识库ID", + "name": "kb_id", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/api/file_upload": { + "post": { + "description": "上传文件到服务器(本地存储或MinIO)", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "文件上传" + ], + "summary": "上传文件", + "parameters": [ + { + "type": "file", + "description": "要上传的文件", + "name": "file", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/api/file_upload/{filename}": { + "delete": { + "description": "删除指定文件", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "文件上传" + ], + "summary": "删除文件", + "parameters": [ + { + "type": "string", + "description": "文件名", + "name": "filename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/api/knowledge/create": { + "post": { + "description": "创建一个新的知识库", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "创建知识库", + "parameters": [ + { + "description": "知识库信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.CreateKnowledgeRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/api/knowledge/list": { + "get": { + "description": "获取所有知识库列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "获取知识库列表", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/api/knowledge/{id}": { + "get": { + "description": "根据ID获取知识库详细信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "获取知识库详情", + "parameters": [ + { + "type": "string", + "description": "知识库ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "404": { + "description": "Not Found", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "put": { + "description": "更新指定知识库的信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "更新知识库", + "parameters": [ + { + "type": "string", + "description": "知识库ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.UpdateKnowledgeRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "delete": { + "description": "删除指定的知识库", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "删除知识库", + "parameters": [ + { + "type": "string", + "description": "知识库ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/api/knowledge/{id}/documents": { + "get": { + "description": "获取指定知识库下的所有文档", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "获取知识库文档列表", + "parameters": [ + { + "type": "string", + "description": "知识库ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "文档状态筛选", + "name": "status", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "post": { + "description": "上传文档到指定知识库", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "上传文档", + "parameters": [ + { + "type": "string", + "description": "知识库ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "file", + "description": "文档文件", + "name": "file", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/api/knowledge/{id}/documents/{doc_id}": { + "delete": { + "description": "删除知识库中的指定文档", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "删除文档", + "parameters": [ + { + "type": "string", + "description": "知识库ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "文档ID", + "name": "doc_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/api/knowledge/{id}/documents/{doc_id}/preview": { + "get": { + "description": "获取文档的解析预览内容", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "获取文档预览", + "parameters": [ + { + "type": "string", + "description": "知识库ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "文档ID", + "name": "doc_id", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/api/knowledge/{id}/documents/{doc_id}/reparse": { + "post": { + "description": "重新解析指定文档(用于更新解析结果)", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "重新解析文档", + "parameters": [ + { + "type": "string", + "description": "知识库ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "文档ID", + "name": "doc_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/auth/login": { + "post": { + "description": "用户登录并获取 JWT Token", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "认证" + ], + "summary": "用户登录", + "parameters": [ + { + "description": "登录请求", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handler.LoginRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.LoginResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/auth/me": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "获取已登录用户的详细信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "认证" + ], + "summary": "获取当前用户信息", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/auth/register": { + "post": { + "description": "新用户注册账号", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "认证" + ], + "summary": "用户注册", + "parameters": [ + { + "description": "注册请求", + "name": "RegisterRequest", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handler.RegisterRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/database/add": { + "post": { + "description": "添加新的数据库连接信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "数据库管理" + ], + "summary": "创建数据库", + "parameters": [ + { + "description": "数据库信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.CreateDatabaseRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/model.DatabaseInfo" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/database/check": { + "post": { + "description": "测试数据库连接是否正常", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "数据库管理" + ], + "summary": "检查数据库连接", + "parameters": [ + { + "description": "数据库连接信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.CheckRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/database/graph/save": { + "post": { + "description": "保存数据库的图谱结构信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "数据库管理" + ], + "summary": "保存图谱信息", + "parameters": [ + { + "description": "图谱信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.SaveGraphRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/database/list": { + "get": { + "description": "获取所有已添加的数据库列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "数据库管理" + ], + "summary": "获取数据库列表", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/database/{id}": { + "get": { + "description": "根据ID获取数据库详细信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "数据库管理" + ], + "summary": "获取数据库详情", + "parameters": [ + { + "type": "string", + "description": "数据库ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/model.DatabaseInfo" + } + }, + "404": { + "description": "Not Found", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "put": { + "description": "更新指定数据库的信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "数据库管理" + ], + "summary": "更新数据库信息", + "parameters": [ + { + "type": "string", + "description": "数据库ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.UpdateDatabaseRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/model.DatabaseInfo" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "404": { + "description": "Not Found", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "delete": { + "description": "删除指定的数据库连接", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "数据库管理" + ], + "summary": "删除数据库", + "parameters": [ + { + "type": "string", + "description": "数据库ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "404": { + "description": "Not Found", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/model/add": { + "post": { + "description": "添加新的AI模型配置", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "模型管理" + ], + "summary": "添加模型", + "parameters": [ + { + "description": "模型信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.CreateModelRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/model/list": { + "get": { + "description": "获取所有已添加的AI模型列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "模型管理" + ], + "summary": "获取模型列表", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/model/test": { + "post": { + "description": "测试AI模型连接是否正常", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "模型管理" + ], + "summary": "测试模型连接", + "parameters": [ + { + "description": "模型测试请求", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.TestModelRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/model/{id}": { + "get": { + "description": "根据ID获取模型详细信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "模型管理" + ], + "summary": "获取模型详情", + "parameters": [ + { + "type": "string", + "description": "模型ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/model.ModelInfo" + } + }, + "404": { + "description": "Not Found", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "put": { + "description": "更新指定模型的信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "模型管理" + ], + "summary": "更新模型", + "parameters": [ + { + "type": "string", + "description": "模型ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.UpdateModelRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "delete": { + "description": "删除指定的AI模型", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "模型管理" + ], + "summary": "删除模型", + "parameters": [ + { + "type": "string", + "description": "模型ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": { + "type": "boolean" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/neo4j/check": { + "post": { + "description": "测试 Neo4j 数据库连接是否正常", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Neo4j" + ], + "summary": "检查 Neo4j 连接", + "parameters": [ + { + "description": "Neo4j连接信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.Neo4jCheckRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/neo4j/graphs": { + "post": { + "description": "获取 Neo4j 中的图谱概览数据", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Neo4j" + ], + "summary": "获取图谱概览", + "parameters": [ + { + "description": "图谱查询请求", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.Neo4jGraphRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/neo4j/nodes": { + "post": { + "description": "获取 Neo4j 中的节点详情", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Neo4j" + ], + "summary": "获取节点列表", + "parameters": [ + { + "description": "节点查询请求", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.Neo4jNodeRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/neo4j/relationships": { + "post": { + "description": "获取 Neo4j 中的关系详情", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Neo4j" + ], + "summary": "获取关系列表", + "parameters": [ + { + "description": "关系查询请求", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.Neo4jRelRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/sub-table/add": { + "post": { + "description": "添加数据库的子表映射关系", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "子表管理" + ], + "summary": "创建子表映射", + "parameters": [ + { + "description": "子表信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.CreateSubTableRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/model.SubTableInfo" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/sub-table/database/{database_id}": { + "get": { + "description": "获取指定数据库的所有子表映射列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "子表管理" + ], + "summary": "获取数据库下所有子表", + "parameters": [ + { + "type": "string", + "description": "数据库ID", + "name": "database_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/sub-table/ddl/{database_id}": { + "get": { + "description": "获取数据库下所有表的DDL语句", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "子表管理" + ], + "summary": "获取表结构DDL", + "parameters": [ + { + "type": "string", + "description": "数据库ID", + "name": "database_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/sub-table/mapping/{database_id}": { + "get": { + "description": "从文件中读取子表映射关系", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "子表管理" + ], + "summary": "从文件获取映射", + "parameters": [ + { + "type": "string", + "description": "数据库ID", + "name": "database_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/sub-table/{id}": { + "get": { + "description": "根据ID获取子表映射详情", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "子表管理" + ], + "summary": "获取子表详情", + "parameters": [ + { + "type": "string", + "description": "子表ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/model.SubTableInfo" + } + }, + "404": { + "description": "Not Found", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "put": { + "description": "更新子表映射信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "子表管理" + ], + "summary": "更新子表映射", + "parameters": [ + { + "type": "string", + "description": "子表ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.UpdateSubTableRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/model.SubTableInfo" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "404": { + "description": "Not Found", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "delete": { + "description": "删除指定的子表映射", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "子表管理" + ], + "summary": "删除子表映射", + "parameters": [ + { + "type": "string", + "description": "子表ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "404": { + "description": "Not Found", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/system/info": { + "get": { + "description": "获取服务器系统信息(CPU、内存等)", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "系统" + ], + "summary": "获取系统信息", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/model.SystemInfo" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + } + }, + "definitions": { + "handler.LoginRequest": { + "type": "object", + "required": [ + "password", + "username" + ], + "properties": { + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "handler.LoginResponse": { + "type": "object", + "properties": { + "token": { + "type": "string" + }, + "user": {} + } + }, + "handler.RegisterRequest": { + "type": "object", + "required": [ + "password", + "username" + ], + "properties": { + "email": { + "type": "string" + }, + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "model.CPUInfo": { + "type": "object", + "properties": { + "core_count": { + "description": "核心数", + "type": "integer" + }, + "model_name": { + "description": "CPU型号", + "type": "string" + }, + "percent": { + "description": "CPU使用率", + "type": "number" + } + } + }, + "model.CheckRequest": { + "type": "object", + "required": [ + "db_type", + "host", + "port", + "username" + ], + "properties": { + "charset": { + "type": "string" + }, + "database": { + "type": "string" + }, + "database_id": { + "description": "可选,用于获取已保存的字段映射", + "type": "string" + }, + "db_type": { + "type": "string" + }, + "host": { + "type": "string" + }, + "password": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "ssl_mode": { + "type": "string" + }, + "uri": { + "description": "Neo4j 连接地址,如 bolt://localhost:7687", + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "model.CreateDatabaseRequest": { + "type": "object", + "required": [ + "db_type", + "host", + "name", + "port", + "username" + ], + "properties": { + "charset": { + "type": "string" + }, + "database": { + "type": "string" + }, + "db_type": { + "type": "string" + }, + "description": { + "type": "string" + }, + "host": { + "type": "string" + }, + "name": { + "type": "string" + }, + "password": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "ssl_mode": { + "type": "string" + }, + "sub_tables": { + "description": "可选,子表配置", + "type": "array", + "items": { + "$ref": "#/definitions/model.CreateSubTableRequest" + } + }, + "username": { + "type": "string" + } + } + }, + "model.CreateKnowledgeRequest": { + "type": "object", + "required": [ + "embedding_model_id", + "llm_model_id", + "name", + "parsing_config" + ], + "properties": { + "description": { + "type": "string" + }, + "embedding_model_id": { + "type": "string" + }, + "llm_model_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parsing_config": { + "$ref": "#/definitions/model.ParsingConfig" + }, + "storage_config": { + "description": "存储配置,不传则使用全局配置", + "allOf": [ + { + "$ref": "#/definitions/model.StorageConfig" + } + ] + } + } + }, + "model.CreateModelRequest": { + "type": "object", + "required": [ + "api_key", + "base_url", + "model", + "model_type", + "name", + "provider" + ], + "properties": { + "api_endpoint": { + "type": "string" + }, + "api_key": { + "type": "string" + }, + "base_url": { + "type": "string" + }, + "model": { + "type": "string" + }, + "model_type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "provider": { + "type": "string" + }, + "status": { + "type": "string" + } + } + }, + "model.CreateSubTableRequest": { + "type": "object", + "required": [ + "database_id", + "parent_table", + "sub_table_name" + ], + "properties": { + "database_id": { + "type": "string" + }, + "ddl": { + "description": "建表DDL", + "type": "string" + }, + "fields": { + "description": "字段映射列表", + "type": "array", + "items": { + "$ref": "#/definitions/model.FieldMapping" + } + }, + "mapping_type": { + "type": "string" + }, + "parent_table": { + "type": "string" + }, + "relation_field": { + "type": "string" + }, + "relation_type": { + "type": "string" + }, + "sub_table_comment": { + "type": "string" + }, + "sub_table_name": { + "type": "string" + } + } + }, + "model.DatabaseInfo": { + "type": "object", + "properties": { + "charset": { + "description": "连接选项", + "type": "string" + }, + "created_at": { + "description": "时间", + "type": "string" + }, + "database": { + "description": "数据库名", + "type": "string" + }, + "db_type": { + "description": "数据库类型: mysql, postgres, mongodb, neo4j等", + "type": "string" + }, + "description": { + "description": "描述", + "type": "string" + }, + "graph_labels": { + "description": "Neo4j 标签列表 (JSON 格式)", + "type": "string" + }, + "graph_relationship": { + "description": "Neo4j 关系类型列表 (JSON 格式)", + "type": "string" + }, + "host": { + "description": "主机地址", + "type": "string" + }, + "id": { + "description": "UUID", + "type": "string" + }, + "name": { + "description": "数据库名称", + "type": "string" + }, + "password": { + "description": "密码(建议加密存储)", + "type": "string" + }, + "port": { + "description": "端口", + "type": "integer" + }, + "selected_label": { + "description": "当前选中的标签", + "type": "string" + }, + "ssl_mode": { + "description": "SSL模式", + "type": "string" + }, + "table_count": { + "description": "子表数量", + "type": "integer" + }, + "updated_at": { + "type": "string" + }, + "uri": { + "description": "Neo4j 专用字段", + "type": "string" + }, + "username": { + "description": "用户名", + "type": "string" + } + } + }, + "model.FieldMapping": { + "type": "object", + "properties": { + "column_name": { + "description": "列名", + "type": "string" + }, + "mapped_name": { + "description": "中文映射名", + "type": "string" + } + } + }, + "model.MemoryInfo": { + "type": "object", + "properties": { + "available": { + "description": "可用(字节)", + "type": "integer" + }, + "available_gb": { + "description": "可用(GB)", + "type": "number" + }, + "percent": { + "description": "使用率", + "type": "number" + }, + "total": { + "description": "总内存(字节)", + "type": "integer" + }, + "total_gb": { + "description": "总内存(GB)", + "type": "number" + }, + "used": { + "description": "已使用(字节)", + "type": "integer" + }, + "used_gb": { + "description": "已使用(GB)", + "type": "number" + } + } + }, + "model.ModelInfo": { + "type": "object", + "properties": { + "api_endpoint": { + "description": "API 端点路径", + "type": "string" + }, + "api_key": { + "description": "API 密钥", + "type": "string" + }, + "base_url": { + "description": "基础 URL", + "type": "string" + }, + "created_at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "model": { + "description": "模型标识", + "type": "string" + }, + "model_type": { + "description": "chat/embedding/rerank/vlm", + "type": "string" + }, + "name": { + "type": "string" + }, + "provider": { + "description": "OpenAI/Ollama", + "type": "string" + }, + "status": { + "description": "active/inactive", + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "model.Neo4jCheckRequest": { + "type": "object", + "required": [ + "host", + "password", + "port", + "username" + ], + "properties": { + "database": { + "description": "可选,默认 neo4j", + "type": "string" + }, + "description": { + "description": "可选,数据库描述", + "type": "string" + }, + "host": { + "type": "string" + }, + "name": { + "description": "数据库名称", + "type": "string" + }, + "password": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "uri": { + "description": "可选,Neo4j 连接地址 (bolt://host:7687)", + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "model.Neo4jGraphRequest": { + "type": "object", + "required": [ + "password", + "uri", + "username" + ], + "properties": { + "database": { + "description": "可选,默认 neo4j", + "type": "string" + }, + "password": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "model.Neo4jNodeRequest": { + "type": "object", + "required": [ + "label", + "password", + "uri", + "username" + ], + "properties": { + "database": { + "type": "string" + }, + "label": { + "type": "string" + }, + "limit": { + "description": "默认 10", + "type": "integer" + }, + "password": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "model.Neo4jRelRequest": { + "type": "object", + "required": [ + "password", + "relationship_type", + "uri", + "username" + ], + "properties": { + "database": { + "type": "string" + }, + "limit": { + "description": "默认 10", + "type": "integer" + }, + "password": { + "type": "string" + }, + "relationship_type": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "model.ParsingConfig": { + "type": "object", + "properties": { + "docling_url": { + "description": "Docling 服务 URL", + "type": "string" + }, + "enable_pdf": { + "description": "是否启用 PDF 解析", + "type": "boolean" + }, + "engine": { + "description": "markitdown / docling", + "type": "string" + }, + "pandoc": { + "description": "是否启用 Pandoc", + "type": "boolean" + }, + "vlm_api_key": { + "description": "API Key", + "type": "string" + }, + "vlm_base_url": { + "description": "自定义 API 地址", + "type": "string" + }, + "vlm_enabled": { + "description": "VLM 配置(用于图片 OCR 等)", + "type": "boolean" + }, + "vlm_model": { + "description": "模型名称", + "type": "string" + }, + "vlm_prompt": { + "description": "自定义提示词", + "type": "string" + }, + "vlm_provider": { + "description": "VLM 提供商: openai, anthropic, local 等", + "type": "string" + } + } + }, + "model.SaveGraphRequest": { + "type": "object", + "required": [ + "databaseId", + "databaseName", + "labels", + "relationshipTypes", + "uri", + "username" + ], + "properties": { + "databaseId": { + "type": "string" + }, + "databaseName": { + "type": "string" + }, + "labels": { + "type": "array", + "items": { + "type": "string" + } + }, + "relationshipTypes": { + "type": "array", + "items": { + "type": "string" + } + }, + "selectedLabel": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "model.StorageConfig": { + "type": "object", + "properties": { + "access_key_id": { + "description": "MinIO/S3 access key", + "type": "string" + }, + "bucket": { + "description": "MinIO/S3 bucket", + "type": "string" + }, + "endpoint": { + "description": "MinIO/S3 endpoint", + "type": "string" + }, + "secret_access_key": { + "description": "MinIO/S3 secret key", + "type": "string" + }, + "type": { + "description": "local / minio / s3", + "type": "string" + }, + "use_ssl": { + "description": "MinIO/S3 use SSL", + "type": "boolean" + } + } + }, + "model.SubTableInfo": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "database_id": { + "description": "关联的数据库ID", + "type": "string" + }, + "ddl": { + "description": "建表 DDL", + "type": "string" + }, + "fields": { + "description": "字段映射列表(返回给前端)", + "type": "array", + "items": { + "$ref": "#/definitions/model.FieldMapping" + } + }, + "id": { + "description": "UUID", + "type": "string" + }, + "mapping_type": { + "description": "映射类型", + "type": "string" + }, + "parent_table": { + "description": "父表名", + "type": "string" + }, + "relation_field": { + "description": "关联字段", + "type": "string" + }, + "relation_type": { + "description": "关联类型", + "type": "string" + }, + "sub_table_comment": { + "description": "子表注释", + "type": "string" + }, + "sub_table_name": { + "description": "子表名", + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "model.SystemInfo": { + "type": "object", + "properties": { + "cpu": { + "$ref": "#/definitions/model.CPUInfo" + }, + "memory": { + "$ref": "#/definitions/model.MemoryInfo" + } + } + }, + "model.TestModelRequest": { + "type": "object", + "required": [ + "api_key", + "base_url", + "model", + "model_type", + "provider" + ], + "properties": { + "api_endpoint": { + "type": "string" + }, + "api_key": { + "type": "string" + }, + "base_url": { + "type": "string" + }, + "model": { + "type": "string" + }, + "model_type": { + "type": "string" + }, + "provider": { + "type": "string" + } + } + }, + "model.UpdateDatabaseRequest": { + "type": "object", + "properties": { + "charset": { + "type": "string" + }, + "database": { + "type": "string" + }, + "db_type": { + "type": "string" + }, + "description": { + "type": "string" + }, + "graph_labels": { + "description": "Neo4j 标签列表 (JSON)", + "type": "string" + }, + "graph_relationship": { + "description": "Neo4j 关系类型列表 (JSON)", + "type": "string" + }, + "host": { + "type": "string" + }, + "name": { + "type": "string" + }, + "password": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "selected_label": { + "description": "当前选中的标签", + "type": "string" + }, + "ssl_mode": { + "type": "string" + }, + "sub_tables": { + "description": "子表配置", + "type": "array", + "items": { + "$ref": "#/definitions/model.CreateSubTableRequest" + } + }, + "table_count": { + "type": "integer" + }, + "uri": { + "description": "Neo4j 连接地址", + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "model.UpdateKnowledgeRequest": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "embedding_model_id": { + "type": "string" + }, + "llm_model_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parsing_config": { + "$ref": "#/definitions/model.ParsingConfig" + }, + "status": { + "type": "string" + }, + "storage_config": { + "$ref": "#/definitions/model.StorageConfig" + } + } + }, + "model.UpdateModelRequest": { + "type": "object", + "properties": { + "api_endpoint": { + "type": "string" + }, + "api_key": { + "type": "string" + }, + "base_url": { + "type": "string" + }, + "model": { + "type": "string" + }, + "model_type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "provider": { + "type": "string" + }, + "status": { + "type": "string" + } + } + }, + "model.UpdateSubTableRequest": { + "type": "object", + "properties": { + "ddl": { + "type": "string" + }, + "mapping_type": { + "type": "string" + }, + "parent_table": { + "type": "string" + }, + "relation_field": { + "type": "string" + }, + "relation_type": { + "type": "string" + }, + "sub_table_comment": { + "type": "string" + }, + "sub_table_name": { + "type": "string" + } + } + } + } +}` + +// SwaggerInfo holds exported Swagger Info so clients can modify it +var SwaggerInfo = &swag.Spec{ + Version: "", + Host: "", + BasePath: "", + Schemes: []string{}, + Title: "", + Description: "", + InfoInstanceName: "swagger", + SwaggerTemplate: docTemplate, + LeftDelim: "{{", + RightDelim: "}}", +} + +func init() { + swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) +} diff --git a/server/docs/swagger.json b/server/docs/swagger.json new file mode 100644 index 0000000..a3cf274 --- /dev/null +++ b/server/docs/swagger.json @@ -0,0 +1,2907 @@ +{ + "swagger": "2.0", + "info": { + "contact": {} + }, + "paths": { + "/api/file_proxy": { + "get": { + "description": "代理访问文件,解决 MinIO 内网和 HTTPS 问题", + "consumes": [ + "application/json" + ], + "produces": [ + "application/octet-stream" + ], + "tags": [ + "文件上传" + ], + "summary": "代理文件访问", + "parameters": [ + { + "type": "string", + "description": "文件Key", + "name": "key", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "知识库ID", + "name": "kb_id", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/api/file_upload": { + "post": { + "description": "上传文件到服务器(本地存储或MinIO)", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "文件上传" + ], + "summary": "上传文件", + "parameters": [ + { + "type": "file", + "description": "要上传的文件", + "name": "file", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/api/file_upload/{filename}": { + "delete": { + "description": "删除指定文件", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "文件上传" + ], + "summary": "删除文件", + "parameters": [ + { + "type": "string", + "description": "文件名", + "name": "filename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/api/knowledge/create": { + "post": { + "description": "创建一个新的知识库", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "创建知识库", + "parameters": [ + { + "description": "知识库信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.CreateKnowledgeRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/api/knowledge/list": { + "get": { + "description": "获取所有知识库列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "获取知识库列表", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/api/knowledge/{id}": { + "get": { + "description": "根据ID获取知识库详细信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "获取知识库详情", + "parameters": [ + { + "type": "string", + "description": "知识库ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "404": { + "description": "Not Found", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "put": { + "description": "更新指定知识库的信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "更新知识库", + "parameters": [ + { + "type": "string", + "description": "知识库ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.UpdateKnowledgeRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "delete": { + "description": "删除指定的知识库", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "删除知识库", + "parameters": [ + { + "type": "string", + "description": "知识库ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/api/knowledge/{id}/documents": { + "get": { + "description": "获取指定知识库下的所有文档", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "获取知识库文档列表", + "parameters": [ + { + "type": "string", + "description": "知识库ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "文档状态筛选", + "name": "status", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "post": { + "description": "上传文档到指定知识库", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "上传文档", + "parameters": [ + { + "type": "string", + "description": "知识库ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "file", + "description": "文档文件", + "name": "file", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/api/knowledge/{id}/documents/{doc_id}": { + "delete": { + "description": "删除知识库中的指定文档", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "删除文档", + "parameters": [ + { + "type": "string", + "description": "知识库ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "文档ID", + "name": "doc_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/api/knowledge/{id}/documents/{doc_id}/preview": { + "get": { + "description": "获取文档的解析预览内容", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "获取文档预览", + "parameters": [ + { + "type": "string", + "description": "知识库ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "文档ID", + "name": "doc_id", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/api/knowledge/{id}/documents/{doc_id}/reparse": { + "post": { + "description": "重新解析指定文档(用于更新解析结果)", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "知识库" + ], + "summary": "重新解析文档", + "parameters": [ + { + "type": "string", + "description": "知识库ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "文档ID", + "name": "doc_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/auth/login": { + "post": { + "description": "用户登录并获取 JWT Token", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "认证" + ], + "summary": "用户登录", + "parameters": [ + { + "description": "登录请求", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handler.LoginRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.LoginResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/auth/me": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "获取已登录用户的详细信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "认证" + ], + "summary": "获取当前用户信息", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/auth/register": { + "post": { + "description": "新用户注册账号", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "认证" + ], + "summary": "用户注册", + "parameters": [ + { + "description": "注册请求", + "name": "RegisterRequest", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handler.RegisterRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/database/add": { + "post": { + "description": "添加新的数据库连接信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "数据库管理" + ], + "summary": "创建数据库", + "parameters": [ + { + "description": "数据库信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.CreateDatabaseRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/model.DatabaseInfo" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/database/check": { + "post": { + "description": "测试数据库连接是否正常", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "数据库管理" + ], + "summary": "检查数据库连接", + "parameters": [ + { + "description": "数据库连接信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.CheckRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/database/graph/save": { + "post": { + "description": "保存数据库的图谱结构信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "数据库管理" + ], + "summary": "保存图谱信息", + "parameters": [ + { + "description": "图谱信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.SaveGraphRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/database/list": { + "get": { + "description": "获取所有已添加的数据库列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "数据库管理" + ], + "summary": "获取数据库列表", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/database/{id}": { + "get": { + "description": "根据ID获取数据库详细信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "数据库管理" + ], + "summary": "获取数据库详情", + "parameters": [ + { + "type": "string", + "description": "数据库ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/model.DatabaseInfo" + } + }, + "404": { + "description": "Not Found", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "put": { + "description": "更新指定数据库的信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "数据库管理" + ], + "summary": "更新数据库信息", + "parameters": [ + { + "type": "string", + "description": "数据库ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.UpdateDatabaseRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/model.DatabaseInfo" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "404": { + "description": "Not Found", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "delete": { + "description": "删除指定的数据库连接", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "数据库管理" + ], + "summary": "删除数据库", + "parameters": [ + { + "type": "string", + "description": "数据库ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "404": { + "description": "Not Found", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/model/add": { + "post": { + "description": "添加新的AI模型配置", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "模型管理" + ], + "summary": "添加模型", + "parameters": [ + { + "description": "模型信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.CreateModelRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/model/list": { + "get": { + "description": "获取所有已添加的AI模型列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "模型管理" + ], + "summary": "获取模型列表", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/model/test": { + "post": { + "description": "测试AI模型连接是否正常", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "模型管理" + ], + "summary": "测试模型连接", + "parameters": [ + { + "description": "模型测试请求", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.TestModelRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/model/{id}": { + "get": { + "description": "根据ID获取模型详细信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "模型管理" + ], + "summary": "获取模型详情", + "parameters": [ + { + "type": "string", + "description": "模型ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/model.ModelInfo" + } + }, + "404": { + "description": "Not Found", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "put": { + "description": "更新指定模型的信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "模型管理" + ], + "summary": "更新模型", + "parameters": [ + { + "type": "string", + "description": "模型ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.UpdateModelRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "delete": { + "description": "删除指定的AI模型", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "模型管理" + ], + "summary": "删除模型", + "parameters": [ + { + "type": "string", + "description": "模型ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": { + "type": "boolean" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/neo4j/check": { + "post": { + "description": "测试 Neo4j 数据库连接是否正常", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Neo4j" + ], + "summary": "检查 Neo4j 连接", + "parameters": [ + { + "description": "Neo4j连接信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.Neo4jCheckRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/neo4j/graphs": { + "post": { + "description": "获取 Neo4j 中的图谱概览数据", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Neo4j" + ], + "summary": "获取图谱概览", + "parameters": [ + { + "description": "图谱查询请求", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.Neo4jGraphRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/neo4j/nodes": { + "post": { + "description": "获取 Neo4j 中的节点详情", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Neo4j" + ], + "summary": "获取节点列表", + "parameters": [ + { + "description": "节点查询请求", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.Neo4jNodeRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/neo4j/relationships": { + "post": { + "description": "获取 Neo4j 中的关系详情", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Neo4j" + ], + "summary": "获取关系列表", + "parameters": [ + { + "description": "关系查询请求", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.Neo4jRelRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/sub-table/add": { + "post": { + "description": "添加数据库的子表映射关系", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "子表管理" + ], + "summary": "创建子表映射", + "parameters": [ + { + "description": "子表信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.CreateSubTableRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/model.SubTableInfo" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/sub-table/database/{database_id}": { + "get": { + "description": "获取指定数据库的所有子表映射列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "子表管理" + ], + "summary": "获取数据库下所有子表", + "parameters": [ + { + "type": "string", + "description": "数据库ID", + "name": "database_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/sub-table/ddl/{database_id}": { + "get": { + "description": "获取数据库下所有表的DDL语句", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "子表管理" + ], + "summary": "获取表结构DDL", + "parameters": [ + { + "type": "string", + "description": "数据库ID", + "name": "database_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/sub-table/mapping/{database_id}": { + "get": { + "description": "从文件中读取子表映射关系", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "子表管理" + ], + "summary": "从文件获取映射", + "parameters": [ + { + "type": "string", + "description": "数据库ID", + "name": "database_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": true + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/sub-table/{id}": { + "get": { + "description": "根据ID获取子表映射详情", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "子表管理" + ], + "summary": "获取子表详情", + "parameters": [ + { + "type": "string", + "description": "子表ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/model.SubTableInfo" + } + }, + "404": { + "description": "Not Found", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "put": { + "description": "更新子表映射信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "子表管理" + ], + "summary": "更新子表映射", + "parameters": [ + { + "type": "string", + "description": "子表ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/model.UpdateSubTableRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/model.SubTableInfo" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "404": { + "description": "Not Found", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + }, + "delete": { + "description": "删除指定的子表映射", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "子表管理" + ], + "summary": "删除子表映射", + "parameters": [ + { + "type": "string", + "description": "子表ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "404": { + "description": "Not Found", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + }, + "/system/info": { + "get": { + "description": "获取服务器系统信息(CPU、内存等)", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "系统" + ], + "summary": "获取系统信息", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/model.SystemInfo" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + } + } + }, + "definitions": { + "handler.LoginRequest": { + "type": "object", + "required": [ + "password", + "username" + ], + "properties": { + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "handler.LoginResponse": { + "type": "object", + "properties": { + "token": { + "type": "string" + }, + "user": {} + } + }, + "handler.RegisterRequest": { + "type": "object", + "required": [ + "password", + "username" + ], + "properties": { + "email": { + "type": "string" + }, + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "model.CPUInfo": { + "type": "object", + "properties": { + "core_count": { + "description": "核心数", + "type": "integer" + }, + "model_name": { + "description": "CPU型号", + "type": "string" + }, + "percent": { + "description": "CPU使用率", + "type": "number" + } + } + }, + "model.CheckRequest": { + "type": "object", + "required": [ + "db_type", + "host", + "port", + "username" + ], + "properties": { + "charset": { + "type": "string" + }, + "database": { + "type": "string" + }, + "database_id": { + "description": "可选,用于获取已保存的字段映射", + "type": "string" + }, + "db_type": { + "type": "string" + }, + "host": { + "type": "string" + }, + "password": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "ssl_mode": { + "type": "string" + }, + "uri": { + "description": "Neo4j 连接地址,如 bolt://localhost:7687", + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "model.CreateDatabaseRequest": { + "type": "object", + "required": [ + "db_type", + "host", + "name", + "port", + "username" + ], + "properties": { + "charset": { + "type": "string" + }, + "database": { + "type": "string" + }, + "db_type": { + "type": "string" + }, + "description": { + "type": "string" + }, + "host": { + "type": "string" + }, + "name": { + "type": "string" + }, + "password": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "ssl_mode": { + "type": "string" + }, + "sub_tables": { + "description": "可选,子表配置", + "type": "array", + "items": { + "$ref": "#/definitions/model.CreateSubTableRequest" + } + }, + "username": { + "type": "string" + } + } + }, + "model.CreateKnowledgeRequest": { + "type": "object", + "required": [ + "embedding_model_id", + "llm_model_id", + "name", + "parsing_config" + ], + "properties": { + "description": { + "type": "string" + }, + "embedding_model_id": { + "type": "string" + }, + "llm_model_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parsing_config": { + "$ref": "#/definitions/model.ParsingConfig" + }, + "storage_config": { + "description": "存储配置,不传则使用全局配置", + "allOf": [ + { + "$ref": "#/definitions/model.StorageConfig" + } + ] + } + } + }, + "model.CreateModelRequest": { + "type": "object", + "required": [ + "api_key", + "base_url", + "model", + "model_type", + "name", + "provider" + ], + "properties": { + "api_endpoint": { + "type": "string" + }, + "api_key": { + "type": "string" + }, + "base_url": { + "type": "string" + }, + "model": { + "type": "string" + }, + "model_type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "provider": { + "type": "string" + }, + "status": { + "type": "string" + } + } + }, + "model.CreateSubTableRequest": { + "type": "object", + "required": [ + "database_id", + "parent_table", + "sub_table_name" + ], + "properties": { + "database_id": { + "type": "string" + }, + "ddl": { + "description": "建表DDL", + "type": "string" + }, + "fields": { + "description": "字段映射列表", + "type": "array", + "items": { + "$ref": "#/definitions/model.FieldMapping" + } + }, + "mapping_type": { + "type": "string" + }, + "parent_table": { + "type": "string" + }, + "relation_field": { + "type": "string" + }, + "relation_type": { + "type": "string" + }, + "sub_table_comment": { + "type": "string" + }, + "sub_table_name": { + "type": "string" + } + } + }, + "model.DatabaseInfo": { + "type": "object", + "properties": { + "charset": { + "description": "连接选项", + "type": "string" + }, + "created_at": { + "description": "时间", + "type": "string" + }, + "database": { + "description": "数据库名", + "type": "string" + }, + "db_type": { + "description": "数据库类型: mysql, postgres, mongodb, neo4j等", + "type": "string" + }, + "description": { + "description": "描述", + "type": "string" + }, + "graph_labels": { + "description": "Neo4j 标签列表 (JSON 格式)", + "type": "string" + }, + "graph_relationship": { + "description": "Neo4j 关系类型列表 (JSON 格式)", + "type": "string" + }, + "host": { + "description": "主机地址", + "type": "string" + }, + "id": { + "description": "UUID", + "type": "string" + }, + "name": { + "description": "数据库名称", + "type": "string" + }, + "password": { + "description": "密码(建议加密存储)", + "type": "string" + }, + "port": { + "description": "端口", + "type": "integer" + }, + "selected_label": { + "description": "当前选中的标签", + "type": "string" + }, + "ssl_mode": { + "description": "SSL模式", + "type": "string" + }, + "table_count": { + "description": "子表数量", + "type": "integer" + }, + "updated_at": { + "type": "string" + }, + "uri": { + "description": "Neo4j 专用字段", + "type": "string" + }, + "username": { + "description": "用户名", + "type": "string" + } + } + }, + "model.FieldMapping": { + "type": "object", + "properties": { + "column_name": { + "description": "列名", + "type": "string" + }, + "mapped_name": { + "description": "中文映射名", + "type": "string" + } + } + }, + "model.MemoryInfo": { + "type": "object", + "properties": { + "available": { + "description": "可用(字节)", + "type": "integer" + }, + "available_gb": { + "description": "可用(GB)", + "type": "number" + }, + "percent": { + "description": "使用率", + "type": "number" + }, + "total": { + "description": "总内存(字节)", + "type": "integer" + }, + "total_gb": { + "description": "总内存(GB)", + "type": "number" + }, + "used": { + "description": "已使用(字节)", + "type": "integer" + }, + "used_gb": { + "description": "已使用(GB)", + "type": "number" + } + } + }, + "model.ModelInfo": { + "type": "object", + "properties": { + "api_endpoint": { + "description": "API 端点路径", + "type": "string" + }, + "api_key": { + "description": "API 密钥", + "type": "string" + }, + "base_url": { + "description": "基础 URL", + "type": "string" + }, + "created_at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "model": { + "description": "模型标识", + "type": "string" + }, + "model_type": { + "description": "chat/embedding/rerank/vlm", + "type": "string" + }, + "name": { + "type": "string" + }, + "provider": { + "description": "OpenAI/Ollama", + "type": "string" + }, + "status": { + "description": "active/inactive", + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "model.Neo4jCheckRequest": { + "type": "object", + "required": [ + "host", + "password", + "port", + "username" + ], + "properties": { + "database": { + "description": "可选,默认 neo4j", + "type": "string" + }, + "description": { + "description": "可选,数据库描述", + "type": "string" + }, + "host": { + "type": "string" + }, + "name": { + "description": "数据库名称", + "type": "string" + }, + "password": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "uri": { + "description": "可选,Neo4j 连接地址 (bolt://host:7687)", + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "model.Neo4jGraphRequest": { + "type": "object", + "required": [ + "password", + "uri", + "username" + ], + "properties": { + "database": { + "description": "可选,默认 neo4j", + "type": "string" + }, + "password": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "model.Neo4jNodeRequest": { + "type": "object", + "required": [ + "label", + "password", + "uri", + "username" + ], + "properties": { + "database": { + "type": "string" + }, + "label": { + "type": "string" + }, + "limit": { + "description": "默认 10", + "type": "integer" + }, + "password": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "model.Neo4jRelRequest": { + "type": "object", + "required": [ + "password", + "relationship_type", + "uri", + "username" + ], + "properties": { + "database": { + "type": "string" + }, + "limit": { + "description": "默认 10", + "type": "integer" + }, + "password": { + "type": "string" + }, + "relationship_type": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "model.ParsingConfig": { + "type": "object", + "properties": { + "docling_url": { + "description": "Docling 服务 URL", + "type": "string" + }, + "enable_pdf": { + "description": "是否启用 PDF 解析", + "type": "boolean" + }, + "engine": { + "description": "markitdown / docling", + "type": "string" + }, + "pandoc": { + "description": "是否启用 Pandoc", + "type": "boolean" + }, + "vlm_api_key": { + "description": "API Key", + "type": "string" + }, + "vlm_base_url": { + "description": "自定义 API 地址", + "type": "string" + }, + "vlm_enabled": { + "description": "VLM 配置(用于图片 OCR 等)", + "type": "boolean" + }, + "vlm_model": { + "description": "模型名称", + "type": "string" + }, + "vlm_prompt": { + "description": "自定义提示词", + "type": "string" + }, + "vlm_provider": { + "description": "VLM 提供商: openai, anthropic, local 等", + "type": "string" + } + } + }, + "model.SaveGraphRequest": { + "type": "object", + "required": [ + "databaseId", + "databaseName", + "labels", + "relationshipTypes", + "uri", + "username" + ], + "properties": { + "databaseId": { + "type": "string" + }, + "databaseName": { + "type": "string" + }, + "labels": { + "type": "array", + "items": { + "type": "string" + } + }, + "relationshipTypes": { + "type": "array", + "items": { + "type": "string" + } + }, + "selectedLabel": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "model.StorageConfig": { + "type": "object", + "properties": { + "access_key_id": { + "description": "MinIO/S3 access key", + "type": "string" + }, + "bucket": { + "description": "MinIO/S3 bucket", + "type": "string" + }, + "endpoint": { + "description": "MinIO/S3 endpoint", + "type": "string" + }, + "secret_access_key": { + "description": "MinIO/S3 secret key", + "type": "string" + }, + "type": { + "description": "local / minio / s3", + "type": "string" + }, + "use_ssl": { + "description": "MinIO/S3 use SSL", + "type": "boolean" + } + } + }, + "model.SubTableInfo": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "database_id": { + "description": "关联的数据库ID", + "type": "string" + }, + "ddl": { + "description": "建表 DDL", + "type": "string" + }, + "fields": { + "description": "字段映射列表(返回给前端)", + "type": "array", + "items": { + "$ref": "#/definitions/model.FieldMapping" + } + }, + "id": { + "description": "UUID", + "type": "string" + }, + "mapping_type": { + "description": "映射类型", + "type": "string" + }, + "parent_table": { + "description": "父表名", + "type": "string" + }, + "relation_field": { + "description": "关联字段", + "type": "string" + }, + "relation_type": { + "description": "关联类型", + "type": "string" + }, + "sub_table_comment": { + "description": "子表注释", + "type": "string" + }, + "sub_table_name": { + "description": "子表名", + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "model.SystemInfo": { + "type": "object", + "properties": { + "cpu": { + "$ref": "#/definitions/model.CPUInfo" + }, + "memory": { + "$ref": "#/definitions/model.MemoryInfo" + } + } + }, + "model.TestModelRequest": { + "type": "object", + "required": [ + "api_key", + "base_url", + "model", + "model_type", + "provider" + ], + "properties": { + "api_endpoint": { + "type": "string" + }, + "api_key": { + "type": "string" + }, + "base_url": { + "type": "string" + }, + "model": { + "type": "string" + }, + "model_type": { + "type": "string" + }, + "provider": { + "type": "string" + } + } + }, + "model.UpdateDatabaseRequest": { + "type": "object", + "properties": { + "charset": { + "type": "string" + }, + "database": { + "type": "string" + }, + "db_type": { + "type": "string" + }, + "description": { + "type": "string" + }, + "graph_labels": { + "description": "Neo4j 标签列表 (JSON)", + "type": "string" + }, + "graph_relationship": { + "description": "Neo4j 关系类型列表 (JSON)", + "type": "string" + }, + "host": { + "type": "string" + }, + "name": { + "type": "string" + }, + "password": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "selected_label": { + "description": "当前选中的标签", + "type": "string" + }, + "ssl_mode": { + "type": "string" + }, + "sub_tables": { + "description": "子表配置", + "type": "array", + "items": { + "$ref": "#/definitions/model.CreateSubTableRequest" + } + }, + "table_count": { + "type": "integer" + }, + "uri": { + "description": "Neo4j 连接地址", + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "model.UpdateKnowledgeRequest": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "embedding_model_id": { + "type": "string" + }, + "llm_model_id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parsing_config": { + "$ref": "#/definitions/model.ParsingConfig" + }, + "status": { + "type": "string" + }, + "storage_config": { + "$ref": "#/definitions/model.StorageConfig" + } + } + }, + "model.UpdateModelRequest": { + "type": "object", + "properties": { + "api_endpoint": { + "type": "string" + }, + "api_key": { + "type": "string" + }, + "base_url": { + "type": "string" + }, + "model": { + "type": "string" + }, + "model_type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "provider": { + "type": "string" + }, + "status": { + "type": "string" + } + } + }, + "model.UpdateSubTableRequest": { + "type": "object", + "properties": { + "ddl": { + "type": "string" + }, + "mapping_type": { + "type": "string" + }, + "parent_table": { + "type": "string" + }, + "relation_field": { + "type": "string" + }, + "relation_type": { + "type": "string" + }, + "sub_table_comment": { + "type": "string" + }, + "sub_table_name": { + "type": "string" + } + } + } + } +} \ No newline at end of file diff --git a/server/docs/swagger.yaml b/server/docs/swagger.yaml new file mode 100644 index 0000000..273524b --- /dev/null +++ b/server/docs/swagger.yaml @@ -0,0 +1,1960 @@ +definitions: + handler.LoginRequest: + properties: + password: + type: string + username: + type: string + required: + - password + - username + type: object + handler.LoginResponse: + properties: + token: + type: string + user: {} + type: object + handler.RegisterRequest: + properties: + email: + type: string + password: + type: string + username: + type: string + required: + - password + - username + type: object + model.CPUInfo: + properties: + core_count: + description: 核心数 + type: integer + model_name: + description: CPU型号 + type: string + percent: + description: CPU使用率 + type: number + type: object + model.CheckRequest: + properties: + charset: + type: string + database: + type: string + database_id: + description: 可选,用于获取已保存的字段映射 + type: string + db_type: + type: string + host: + type: string + password: + type: string + port: + type: integer + ssl_mode: + type: string + uri: + description: Neo4j 连接地址,如 bolt://localhost:7687 + type: string + username: + type: string + required: + - db_type + - host + - port + - username + type: object + model.CreateDatabaseRequest: + properties: + charset: + type: string + database: + type: string + db_type: + type: string + description: + type: string + host: + type: string + name: + type: string + password: + type: string + port: + type: integer + ssl_mode: + type: string + sub_tables: + description: 可选,子表配置 + items: + $ref: '#/definitions/model.CreateSubTableRequest' + type: array + username: + type: string + required: + - db_type + - host + - name + - port + - username + type: object + model.CreateKnowledgeRequest: + properties: + description: + type: string + embedding_model_id: + type: string + llm_model_id: + type: string + name: + type: string + parsing_config: + $ref: '#/definitions/model.ParsingConfig' + storage_config: + allOf: + - $ref: '#/definitions/model.StorageConfig' + description: 存储配置,不传则使用全局配置 + required: + - embedding_model_id + - llm_model_id + - name + - parsing_config + type: object + model.CreateModelRequest: + properties: + api_endpoint: + type: string + api_key: + type: string + base_url: + type: string + model: + type: string + model_type: + type: string + name: + type: string + provider: + type: string + status: + type: string + required: + - api_key + - base_url + - model + - model_type + - name + - provider + type: object + model.CreateSubTableRequest: + properties: + database_id: + type: string + ddl: + description: 建表DDL + type: string + fields: + description: 字段映射列表 + items: + $ref: '#/definitions/model.FieldMapping' + type: array + mapping_type: + type: string + parent_table: + type: string + relation_field: + type: string + relation_type: + type: string + sub_table_comment: + type: string + sub_table_name: + type: string + required: + - database_id + - parent_table + - sub_table_name + type: object + model.DatabaseInfo: + properties: + charset: + description: 连接选项 + type: string + created_at: + description: 时间 + type: string + database: + description: 数据库名 + type: string + db_type: + description: '数据库类型: mysql, postgres, mongodb, neo4j等' + type: string + description: + description: 描述 + type: string + graph_labels: + description: Neo4j 标签列表 (JSON 格式) + type: string + graph_relationship: + description: Neo4j 关系类型列表 (JSON 格式) + type: string + host: + description: 主机地址 + type: string + id: + description: UUID + type: string + name: + description: 数据库名称 + type: string + password: + description: 密码(建议加密存储) + type: string + port: + description: 端口 + type: integer + selected_label: + description: 当前选中的标签 + type: string + ssl_mode: + description: SSL模式 + type: string + table_count: + description: 子表数量 + type: integer + updated_at: + type: string + uri: + description: Neo4j 专用字段 + type: string + username: + description: 用户名 + type: string + type: object + model.FieldMapping: + properties: + column_name: + description: 列名 + type: string + mapped_name: + description: 中文映射名 + type: string + type: object + model.MemoryInfo: + properties: + available: + description: 可用(字节) + type: integer + available_gb: + description: 可用(GB) + type: number + percent: + description: 使用率 + type: number + total: + description: 总内存(字节) + type: integer + total_gb: + description: 总内存(GB) + type: number + used: + description: 已使用(字节) + type: integer + used_gb: + description: 已使用(GB) + type: number + type: object + model.ModelInfo: + properties: + api_endpoint: + description: API 端点路径 + type: string + api_key: + description: API 密钥 + type: string + base_url: + description: 基础 URL + type: string + created_at: + type: string + id: + type: string + model: + description: 模型标识 + type: string + model_type: + description: chat/embedding/rerank/vlm + type: string + name: + type: string + provider: + description: OpenAI/Ollama + type: string + status: + description: active/inactive + type: string + updated_at: + type: string + type: object + model.Neo4jCheckRequest: + properties: + database: + description: 可选,默认 neo4j + type: string + description: + description: 可选,数据库描述 + type: string + host: + type: string + name: + description: 数据库名称 + type: string + password: + type: string + port: + type: integer + uri: + description: 可选,Neo4j 连接地址 (bolt://host:7687) + type: string + username: + type: string + required: + - host + - password + - port + - username + type: object + model.Neo4jGraphRequest: + properties: + database: + description: 可选,默认 neo4j + type: string + password: + type: string + uri: + type: string + username: + type: string + required: + - password + - uri + - username + type: object + model.Neo4jNodeRequest: + properties: + database: + type: string + label: + type: string + limit: + description: 默认 10 + type: integer + password: + type: string + uri: + type: string + username: + type: string + required: + - label + - password + - uri + - username + type: object + model.Neo4jRelRequest: + properties: + database: + type: string + limit: + description: 默认 10 + type: integer + password: + type: string + relationship_type: + type: string + uri: + type: string + username: + type: string + required: + - password + - relationship_type + - uri + - username + type: object + model.ParsingConfig: + properties: + docling_url: + description: Docling 服务 URL + type: string + enable_pdf: + description: 是否启用 PDF 解析 + type: boolean + engine: + description: markitdown / docling + type: string + pandoc: + description: 是否启用 Pandoc + type: boolean + vlm_api_key: + description: API Key + type: string + vlm_base_url: + description: 自定义 API 地址 + type: string + vlm_enabled: + description: VLM 配置(用于图片 OCR 等) + type: boolean + vlm_model: + description: 模型名称 + type: string + vlm_prompt: + description: 自定义提示词 + type: string + vlm_provider: + description: 'VLM 提供商: openai, anthropic, local 等' + type: string + type: object + model.SaveGraphRequest: + properties: + databaseId: + type: string + databaseName: + type: string + labels: + items: + type: string + type: array + relationshipTypes: + items: + type: string + type: array + selectedLabel: + type: string + uri: + type: string + username: + type: string + required: + - databaseId + - databaseName + - labels + - relationshipTypes + - uri + - username + type: object + model.StorageConfig: + properties: + access_key_id: + description: MinIO/S3 access key + type: string + bucket: + description: MinIO/S3 bucket + type: string + endpoint: + description: MinIO/S3 endpoint + type: string + secret_access_key: + description: MinIO/S3 secret key + type: string + type: + description: local / minio / s3 + type: string + use_ssl: + description: MinIO/S3 use SSL + type: boolean + type: object + model.SubTableInfo: + properties: + created_at: + type: string + database_id: + description: 关联的数据库ID + type: string + ddl: + description: 建表 DDL + type: string + fields: + description: 字段映射列表(返回给前端) + items: + $ref: '#/definitions/model.FieldMapping' + type: array + id: + description: UUID + type: string + mapping_type: + description: 映射类型 + type: string + parent_table: + description: 父表名 + type: string + relation_field: + description: 关联字段 + type: string + relation_type: + description: 关联类型 + type: string + sub_table_comment: + description: 子表注释 + type: string + sub_table_name: + description: 子表名 + type: string + updated_at: + type: string + type: object + model.SystemInfo: + properties: + cpu: + $ref: '#/definitions/model.CPUInfo' + memory: + $ref: '#/definitions/model.MemoryInfo' + type: object + model.TestModelRequest: + properties: + api_endpoint: + type: string + api_key: + type: string + base_url: + type: string + model: + type: string + model_type: + type: string + provider: + type: string + required: + - api_key + - base_url + - model + - model_type + - provider + type: object + model.UpdateDatabaseRequest: + properties: + charset: + type: string + database: + type: string + db_type: + type: string + description: + type: string + graph_labels: + description: Neo4j 标签列表 (JSON) + type: string + graph_relationship: + description: Neo4j 关系类型列表 (JSON) + type: string + host: + type: string + name: + type: string + password: + type: string + port: + type: integer + selected_label: + description: 当前选中的标签 + type: string + ssl_mode: + type: string + sub_tables: + description: 子表配置 + items: + $ref: '#/definitions/model.CreateSubTableRequest' + type: array + table_count: + type: integer + uri: + description: Neo4j 连接地址 + type: string + username: + type: string + type: object + model.UpdateKnowledgeRequest: + properties: + description: + type: string + embedding_model_id: + type: string + llm_model_id: + type: string + name: + type: string + parsing_config: + $ref: '#/definitions/model.ParsingConfig' + status: + type: string + storage_config: + $ref: '#/definitions/model.StorageConfig' + type: object + model.UpdateModelRequest: + properties: + api_endpoint: + type: string + api_key: + type: string + base_url: + type: string + model: + type: string + model_type: + type: string + name: + type: string + provider: + type: string + status: + type: string + type: object + model.UpdateSubTableRequest: + properties: + ddl: + type: string + mapping_type: + type: string + parent_table: + type: string + relation_field: + type: string + relation_type: + type: string + sub_table_comment: + type: string + sub_table_name: + type: string + type: object +info: + contact: {} +paths: + /api/file_proxy: + get: + consumes: + - application/json + description: 代理访问文件,解决 MinIO 内网和 HTTPS 问题 + parameters: + - description: 文件Key + in: query + name: key + required: true + type: string + - description: 知识库ID + in: query + name: kb_id + type: string + produces: + - application/octet-stream + responses: + "200": + description: OK + schema: + type: file + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 代理文件访问 + tags: + - 文件上传 + /api/file_upload: + post: + consumes: + - multipart/form-data + description: 上传文件到服务器(本地存储或MinIO) + parameters: + - description: 要上传的文件 + in: formData + name: file + required: true + type: file + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 上传文件 + tags: + - 文件上传 + /api/file_upload/{filename}: + delete: + consumes: + - application/json + description: 删除指定文件 + parameters: + - description: 文件名 + in: path + name: filename + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 删除文件 + tags: + - 文件上传 + /api/knowledge/{id}: + delete: + consumes: + - application/json + description: 删除指定的知识库 + parameters: + - description: 知识库ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 删除知识库 + tags: + - 知识库 + get: + consumes: + - application/json + description: 根据ID获取知识库详细信息 + parameters: + - description: 知识库ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "404": + description: Not Found + schema: + additionalProperties: + type: string + type: object + summary: 获取知识库详情 + tags: + - 知识库 + put: + consumes: + - application/json + description: 更新指定知识库的信息 + parameters: + - description: 知识库ID + in: path + name: id + required: true + type: string + - description: 更新信息 + in: body + name: request + required: true + schema: + $ref: '#/definitions/model.UpdateKnowledgeRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 更新知识库 + tags: + - 知识库 + /api/knowledge/{id}/documents: + get: + consumes: + - application/json + description: 获取指定知识库下的所有文档 + parameters: + - description: 知识库ID + in: path + name: id + required: true + type: string + - description: 文档状态筛选 + in: query + name: status + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 获取知识库文档列表 + tags: + - 知识库 + post: + consumes: + - multipart/form-data + description: 上传文档到指定知识库 + parameters: + - description: 知识库ID + in: path + name: id + required: true + type: string + - description: 文档文件 + in: formData + name: file + required: true + type: file + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 上传文档 + tags: + - 知识库 + /api/knowledge/{id}/documents/{doc_id}: + delete: + consumes: + - application/json + description: 删除知识库中的指定文档 + parameters: + - description: 知识库ID + in: path + name: id + required: true + type: string + - description: 文档ID + in: path + name: doc_id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 删除文档 + tags: + - 知识库 + /api/knowledge/{id}/documents/{doc_id}/preview: + get: + consumes: + - application/json + description: 获取文档的解析预览内容 + parameters: + - description: 知识库ID + in: path + name: id + required: true + type: string + - description: 文档ID + in: path + name: doc_id + required: true + type: string + - description: 页码 + in: query + name: page + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 获取文档预览 + tags: + - 知识库 + /api/knowledge/{id}/documents/{doc_id}/reparse: + post: + consumes: + - application/json + description: 重新解析指定文档(用于更新解析结果) + parameters: + - description: 知识库ID + in: path + name: id + required: true + type: string + - description: 文档ID + in: path + name: doc_id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 重新解析文档 + tags: + - 知识库 + /api/knowledge/create: + post: + consumes: + - application/json + description: 创建一个新的知识库 + parameters: + - description: 知识库信息 + in: body + name: request + required: true + schema: + $ref: '#/definitions/model.CreateKnowledgeRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + summary: 创建知识库 + tags: + - 知识库 + /api/knowledge/list: + get: + consumes: + - application/json + description: 获取所有知识库列表 + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 获取知识库列表 + tags: + - 知识库 + /auth/login: + post: + consumes: + - application/json + description: 用户登录并获取 JWT Token + parameters: + - description: 登录请求 + in: body + name: request + required: true + schema: + $ref: '#/definitions/handler.LoginRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.LoginResponse' + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "401": + description: Unauthorized + schema: + additionalProperties: + type: string + type: object + summary: 用户登录 + tags: + - 认证 + /auth/me: + get: + consumes: + - application/json + description: 获取已登录用户的详细信息 + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "401": + description: Unauthorized + schema: + additionalProperties: + type: string + type: object + security: + - BearerAuth: [] + summary: 获取当前用户信息 + tags: + - 认证 + /auth/register: + post: + consumes: + - application/json + description: 新用户注册账号 + parameters: + - description: 注册请求 + in: body + name: RegisterRequest + required: true + schema: + $ref: '#/definitions/handler.RegisterRequest' + produces: + - application/json + responses: + "201": + description: Created + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + summary: 用户注册 + tags: + - 认证 + /database/{id}: + delete: + consumes: + - application/json + description: 删除指定的数据库连接 + parameters: + - description: 数据库ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: + type: string + type: object + "404": + description: Not Found + schema: + additionalProperties: + type: string + type: object + summary: 删除数据库 + tags: + - 数据库管理 + get: + consumes: + - application/json + description: 根据ID获取数据库详细信息 + parameters: + - description: 数据库ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/model.DatabaseInfo' + "404": + description: Not Found + schema: + additionalProperties: + type: string + type: object + summary: 获取数据库详情 + tags: + - 数据库管理 + put: + consumes: + - application/json + description: 更新指定数据库的信息 + parameters: + - description: 数据库ID + in: path + name: id + required: true + type: string + - description: 更新信息 + in: body + name: request + required: true + schema: + $ref: '#/definitions/model.UpdateDatabaseRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/model.DatabaseInfo' + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "404": + description: Not Found + schema: + additionalProperties: + type: string + type: object + summary: 更新数据库信息 + tags: + - 数据库管理 + /database/add: + post: + consumes: + - application/json + description: 添加新的数据库连接信息 + parameters: + - description: 数据库信息 + in: body + name: request + required: true + schema: + $ref: '#/definitions/model.CreateDatabaseRequest' + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/model.DatabaseInfo' + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 创建数据库 + tags: + - 数据库管理 + /database/check: + post: + consumes: + - application/json + description: 测试数据库连接是否正常 + parameters: + - description: 数据库连接信息 + in: body + name: request + required: true + schema: + $ref: '#/definitions/model.CheckRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 检查数据库连接 + tags: + - 数据库管理 + /database/graph/save: + post: + consumes: + - application/json + description: 保存数据库的图谱结构信息 + parameters: + - description: 图谱信息 + in: body + name: request + required: true + schema: + $ref: '#/definitions/model.SaveGraphRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 保存图谱信息 + tags: + - 数据库管理 + /database/list: + get: + consumes: + - application/json + description: 获取所有已添加的数据库列表 + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 获取数据库列表 + tags: + - 数据库管理 + /model/{id}: + delete: + consumes: + - application/json + description: 删除指定的AI模型 + parameters: + - description: 模型ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: + type: boolean + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 删除模型 + tags: + - 模型管理 + get: + consumes: + - application/json + description: 根据ID获取模型详细信息 + parameters: + - description: 模型ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/model.ModelInfo' + "404": + description: Not Found + schema: + additionalProperties: + type: string + type: object + summary: 获取模型详情 + tags: + - 模型管理 + put: + consumes: + - application/json + description: 更新指定模型的信息 + parameters: + - description: 模型ID + in: path + name: id + required: true + type: string + - description: 更新信息 + in: body + name: request + required: true + schema: + $ref: '#/definitions/model.UpdateModelRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 更新模型 + tags: + - 模型管理 + /model/add: + post: + consumes: + - application/json + description: 添加新的AI模型配置 + parameters: + - description: 模型信息 + in: body + name: request + required: true + schema: + $ref: '#/definitions/model.CreateModelRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 添加模型 + tags: + - 模型管理 + /model/list: + get: + consumes: + - application/json + description: 获取所有已添加的AI模型列表 + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 获取模型列表 + tags: + - 模型管理 + /model/test: + post: + consumes: + - application/json + description: 测试AI模型连接是否正常 + parameters: + - description: 模型测试请求 + in: body + name: request + required: true + schema: + $ref: '#/definitions/model.TestModelRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 测试模型连接 + tags: + - 模型管理 + /neo4j/check: + post: + consumes: + - application/json + description: 测试 Neo4j 数据库连接是否正常 + parameters: + - description: Neo4j连接信息 + in: body + name: request + required: true + schema: + $ref: '#/definitions/model.Neo4jCheckRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 检查 Neo4j 连接 + tags: + - Neo4j + /neo4j/graphs: + post: + consumes: + - application/json + description: 获取 Neo4j 中的图谱概览数据 + parameters: + - description: 图谱查询请求 + in: body + name: request + required: true + schema: + $ref: '#/definitions/model.Neo4jGraphRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 获取图谱概览 + tags: + - Neo4j + /neo4j/nodes: + post: + consumes: + - application/json + description: 获取 Neo4j 中的节点详情 + parameters: + - description: 节点查询请求 + in: body + name: request + required: true + schema: + $ref: '#/definitions/model.Neo4jNodeRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 获取节点列表 + tags: + - Neo4j + /neo4j/relationships: + post: + consumes: + - application/json + description: 获取 Neo4j 中的关系详情 + parameters: + - description: 关系查询请求 + in: body + name: request + required: true + schema: + $ref: '#/definitions/model.Neo4jRelRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 获取关系列表 + tags: + - Neo4j + /sub-table/{id}: + delete: + consumes: + - application/json + description: 删除指定的子表映射 + parameters: + - description: 子表ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: + type: string + type: object + "404": + description: Not Found + schema: + additionalProperties: + type: string + type: object + summary: 删除子表映射 + tags: + - 子表管理 + get: + consumes: + - application/json + description: 根据ID获取子表映射详情 + parameters: + - description: 子表ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/model.SubTableInfo' + "404": + description: Not Found + schema: + additionalProperties: + type: string + type: object + summary: 获取子表详情 + tags: + - 子表管理 + put: + consumes: + - application/json + description: 更新子表映射信息 + parameters: + - description: 子表ID + in: path + name: id + required: true + type: string + - description: 更新信息 + in: body + name: request + required: true + schema: + $ref: '#/definitions/model.UpdateSubTableRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/model.SubTableInfo' + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "404": + description: Not Found + schema: + additionalProperties: + type: string + type: object + summary: 更新子表映射 + tags: + - 子表管理 + /sub-table/add: + post: + consumes: + - application/json + description: 添加数据库的子表映射关系 + parameters: + - description: 子表信息 + in: body + name: request + required: true + schema: + $ref: '#/definitions/model.CreateSubTableRequest' + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/model.SubTableInfo' + "400": + description: Bad Request + schema: + additionalProperties: + type: string + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 创建子表映射 + tags: + - 子表管理 + /sub-table/database/{database_id}: + get: + consumes: + - application/json + description: 获取指定数据库的所有子表映射列表 + parameters: + - description: 数据库ID + in: path + name: database_id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 获取数据库下所有子表 + tags: + - 子表管理 + /sub-table/ddl/{database_id}: + get: + consumes: + - application/json + description: 获取数据库下所有表的DDL语句 + parameters: + - description: 数据库ID + in: path + name: database_id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 获取表结构DDL + tags: + - 子表管理 + /sub-table/mapping/{database_id}: + get: + consumes: + - application/json + description: 从文件中读取子表映射关系 + parameters: + - description: 数据库ID + in: path + name: database_id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + additionalProperties: true + type: object + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 从文件获取映射 + tags: + - 子表管理 + /system/info: + get: + consumes: + - application/json + description: 获取服务器系统信息(CPU、内存等) + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/model.SystemInfo' + "500": + description: Internal Server Error + schema: + additionalProperties: + type: string + type: object + summary: 获取系统信息 + tags: + - 系统 +swagger: "2.0" diff --git a/server/go.mod b/server/go.mod index 22d149b..fd632a0 100644 --- a/server/go.mod +++ b/server/go.mod @@ -1,78 +1,115 @@ module x-agents/server -go 1.25 +go 1.25.0 require ( - github.com/gin-gonic/gin v1.9.1 + github.com/gin-gonic/gin v1.12.0 github.com/go-sql-driver/mysql v1.7.0 github.com/golang-jwt/jwt/v5 v5.2.0 github.com/google/uuid v1.6.0 github.com/lib/pq v1.10.9 github.com/spf13/viper v1.18.2 - golang.org/x/crypto v0.46.0 + golang.org/x/crypto v0.48.0 gorm.io/driver/mysql v1.5.2 gorm.io/gorm v1.25.5 ) require ( - github.com/bytedance/sonic v1.9.1 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/KyleBanks/depth v1.2.1 // indirect + github.com/PuerkitoBio/purell v1.2.1 // indirect + github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect + github.com/bytedance/gopkg v0.1.3 // indirect + github.com/bytedance/sonic v1.15.0 // indirect + github.com/bytedance/sonic/loader v0.5.0 // indirect + github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect + github.com/cloudwego/base64x v0.1.6 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.13 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect github.com/go-ini/ini v1.67.0 // indirect github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-openapi/jsonpointer v0.22.5 // indirect + github.com/go-openapi/jsonreference v0.21.5 // indirect + github.com/go-openapi/spec v0.22.4 // indirect + github.com/go-openapi/swag v0.25.5 // indirect + github.com/go-openapi/swag/conv v0.25.5 // indirect + github.com/go-openapi/swag/jsonname v0.25.5 // indirect + github.com/go-openapi/swag/jsonutils v0.25.5 // indirect + github.com/go-openapi/swag/loading v0.25.5 // indirect + github.com/go-openapi/swag/stringutils v0.25.5 // indirect + github.com/go-openapi/swag/typeutils v0.25.5 // indirect + github.com/go-openapi/swag/yamlutils v0.25.5 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.14.0 // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/go-playground/validator/v10 v10.30.1 // indirect + github.com/goccy/go-json v0.10.5 // indirect + github.com/goccy/go-yaml v1.19.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.18.2 // indirect - github.com/klauspost/cpuid/v2 v2.2.11 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/klauspost/crc32 v1.3.0 // indirect - github.com/leodido/go-urn v1.2.4 // indirect + github.com/leodido/go-urn v1.4.0 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.7 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mailru/easyjson v0.9.1 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/minio/crc64nvme v1.1.1 // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/minio/minio-go/v7 v7.0.99 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/philhofer/fwd v1.2.0 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/quic-go/qpack v0.6.0 // indirect + github.com/quic-go/quic-go v0.59.0 // indirect github.com/rs/xid v1.6.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/shirou/gopsutil/v3 v3.24.5 // indirect + github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.6.0 // indirect + github.com/swaggo/files v1.0.1 // indirect + github.com/swaggo/gin-swagger v1.6.1 // indirect + github.com/swaggo/swag v1.16.6 // indirect github.com/tinylib/msgp v1.6.1 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.11 // indirect + github.com/ugorji/go/codec v1.3.1 // indirect + github.com/urfave/cli/v2 v2.27.7 // indirect + github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect + go.mongodb.org/mongo-driver/v2 v2.5.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect + go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/arch v0.3.0 // indirect + golang.org/x/arch v0.25.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/net v0.48.0 // indirect - golang.org/x/sys v0.39.0 // indirect - golang.org/x/text v0.32.0 // indirect + golang.org/x/mod v0.33.0 // indirect + golang.org/x/net v0.51.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/sys v0.42.0 // indirect + golang.org/x/text v0.34.0 // indirect + golang.org/x/tools v0.42.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect google.golang.org/grpc v1.79.2 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect ) diff --git a/server/go.sum b/server/go.sum index 1902d11..a96c9ed 100644 --- a/server/go.sum +++ b/server/go.sum @@ -1,9 +1,29 @@ +github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= +github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/PuerkitoBio/purell v1.2.1 h1:QsZ4TjvwiMpat6gBCBxEQI0rcS9ehtkKtSpiUnd9N28= +github.com/PuerkitoBio/purell v1.2.1/go.mod h1:ZwHcC/82TOaovDi//J/804umJFFmbOHPngi8iYYv/Eo= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M= +github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= +github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE= +github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k= +github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE= +github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= +github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= +github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA= +github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= +github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= +github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= +github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= +github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -16,14 +36,42 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM= +github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/gin-gonic/gin v1.12.0 h1:b3YAbrZtnf8N//yjKeU2+MQsh2mY5htkZidOM7O0wG8= +github.com/gin-gonic/gin v1.12.0/go.mod h1:VxccKfsSllpKshkBWgVgRniFFAzFb9csfngsqANjnLc= github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-openapi/jsonpointer v0.22.5 h1:8on/0Yp4uTb9f4XvTrM2+1CPrV05QPZXu+rvu2o9jcA= +github.com/go-openapi/jsonpointer v0.22.5/go.mod h1:gyUR3sCvGSWchA2sUBJGluYMbe1zazrYWIkWPjjMUY0= +github.com/go-openapi/jsonreference v0.21.5 h1:6uCGVXU/aNF13AQNggxfysJ+5ZcU4nEAe+pJyVWRdiE= +github.com/go-openapi/jsonreference v0.21.5/go.mod h1:u25Bw85sX4E2jzFodh1FOKMTZLcfifd1Q+iKKOUxExw= +github.com/go-openapi/spec v0.22.4 h1:4pxGjipMKu0FzFiu/DPwN3CTBRlVM2yLf/YTWorYfDQ= +github.com/go-openapi/spec v0.22.4/go.mod h1:WQ6Ai0VPWMZgMT4XySjlRIE6GP1bGQOtEThn3gcWLtQ= +github.com/go-openapi/swag v0.25.5 h1:pNkwbUEeGwMtcgxDr+2GBPAk4kT+kJ+AaB+TMKAg+TU= +github.com/go-openapi/swag v0.25.5/go.mod h1:B3RT6l8q7X803JRxa2e59tHOiZlX1t8viplOcs9CwTA= +github.com/go-openapi/swag/conv v0.25.5 h1:wAXBYEXJjoKwE5+vc9YHhpQOFj2JYBMF2DUi+tGu97g= +github.com/go-openapi/swag/conv v0.25.5/go.mod h1:CuJ1eWvh1c4ORKx7unQnFGyvBbNlRKbnRyAvDvzWA4k= +github.com/go-openapi/swag/jsonname v0.25.5 h1:8p150i44rv/Drip4vWI3kGi9+4W9TdI3US3uUYSFhSo= +github.com/go-openapi/swag/jsonname v0.25.5/go.mod h1:jNqqikyiAK56uS7n8sLkdaNY/uq6+D2m2LANat09pKU= +github.com/go-openapi/swag/jsonutils v0.25.5 h1:XUZF8awQr75MXeC+/iaw5usY/iM7nXPDwdG3Jbl9vYo= +github.com/go-openapi/swag/jsonutils v0.25.5/go.mod h1:48FXUaz8YsDAA9s5AnaUvAmry1UcLcNVWUjY42XkrN4= +github.com/go-openapi/swag/loading v0.25.5 h1:odQ/umlIZ1ZVRteI6ckSrvP6e2w9UTF5qgNdemJHjuU= +github.com/go-openapi/swag/loading v0.25.5/go.mod h1:I8A8RaaQ4DApxhPSWLNYWh9NvmX2YKMoB9nwvv6oW6g= +github.com/go-openapi/swag/stringutils v0.25.5 h1:NVkoDOA8YBgtAR/zvCx5rhJKtZF3IzXcDdwOsYzrB6M= +github.com/go-openapi/swag/stringutils v0.25.5/go.mod h1:PKK8EZdu4QJq8iezt17HM8RXnLAzY7gW0O1KKarrZII= +github.com/go-openapi/swag/typeutils v0.25.5 h1:EFJ+PCga2HfHGdo8s8VJXEVbeXRCYwzzr9u4rJk7L7E= +github.com/go-openapi/swag/typeutils v0.25.5/go.mod h1:itmFmScAYE1bSD8C4rS0W+0InZUBrB2xSPbWt6DLGuc= +github.com/go-openapi/swag/yamlutils v0.25.5 h1:kASCIS+oIeoc55j28T4o8KwlV2S4ZLPT6G0iq2SSbVQ= +github.com/go-openapi/swag/yamlutils v0.25.5/go.mod h1:Gek1/SjjfbYvM+Iq4QGwa/2lEXde9n2j4a3wI3pNuOQ= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -32,10 +80,16 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w= +github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM= github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM= +github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= @@ -56,6 +110,8 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk= @@ -66,22 +122,31 @@ github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZX github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU= github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/klauspost/crc32 v1.3.0 h1:sSmTt3gUt81RP655XGZPElI0PelVTZ6YwCRnPSupoFM= github.com/klauspost/crc32 v1.3.0/go.mod h1:D7kQaZhnkX/Y0tstFGf8VUzv2UofNGqCjnC3zdHB0Hw= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/minio/crc64nvme v1.1.1 h1:8dwx/Pz49suywbO+auHCBpCtlW1OfpcLN7wYgVR6wAI= github.com/minio/crc64nvme v1.1.1/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= @@ -97,6 +162,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -104,16 +171,24 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8= +github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII= +github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw= +github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= @@ -127,6 +202,7 @@ github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMV github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -136,8 +212,16 @@ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE= +github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg= +github.com/swaggo/gin-swagger v1.6.1 h1:Ri06G4gc9N4t4k8hekMigJ9zKTFSlqj/9paAQCQs7cY= +github.com/swaggo/gin-swagger v1.6.1/go.mod h1:LQ+hJStHakCWRiK/YNYtJOu4mR2FP+pxLnILT/qNiTw= +github.com/swaggo/swag v1.16.6 h1:qBNcx53ZaX+M5dxVyTrgQ0PJ/ACK+NzhwcbieTt+9yI= +github.com/swaggo/swag v1.16.6/go.mod h1:ngP2etMK5a0P3QBizic5MEwpRmluJZPHjXcMoj4Xesg= github.com/tinylib/msgp v1.6.1 h1:ESRv8eL3u+DNHUoSAAQRE50Hm162zqAnBoGv9PzScPY= github.com/tinylib/msgp v1.6.1/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= @@ -148,30 +232,66 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY= +github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= +github.com/urfave/cli/v2 v2.27.7 h1:bH59vdhbjLv3LAvIu6gd0usJHgoTTPhCFib8qqOwXYU= +github.com/urfave/cli/v2 v2.27.7/go.mod h1:CyNAG/xg+iAOg0N4MPGZqVmv2rCoP267496AOXUZjA4= +github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 h1:FnBeRrxr7OU4VvAzt5X7s6266i6cSVkkFPS0TuXWbIg= +github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.mongodb.org/mongo-driver/v2 v2.5.0 h1:yXUhImUjjAInNcpTcAlPHiT7bIXhshCTL3jVBkF3xaE= +go.mongodb.org/mongo-driver/v2 v2.5.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= +go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= +go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.25.0 h1:qnk6Ksugpi5Bz32947rkUgDt9/s5qvqDPl/gBKdMJLE= +golang.org/x/arch v0.25.0/go.mod h1:0X+GdSIP+kL5wPmpK7sdkEVTt2XoYP0cSjQSbZBwOi8= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= +golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -181,10 +301,29 @@ golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= @@ -196,11 +335,15 @@ google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -209,4 +352,7 @@ gorm.io/driver/mysql v1.5.2/go.mod h1:pQLhh1Ut/WUAySdTHwBpBv6+JKcj+ua4ZFx1QQTBzb gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls= gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/server/internal/handler/auth_handler.go b/server/internal/handler/auth_handler.go index 9ea874c..fef59a6 100644 --- a/server/internal/handler/auth_handler.go +++ b/server/internal/handler/auth_handler.go @@ -2,12 +2,57 @@ package handler import ( "net/http" + "strings" "x-agents/server/internal/service" "github.com/gin-gonic/gin" ) +// maskEmail 邮箱脱敏,只显示前后各1个字符 +func maskEmail(email string) string { + if email == "" { + return "" + } + parts := strings.Split(email, "@") + if len(parts) != 2 { + return "***" + } + local := parts[0] + domain := parts[1] + if len(local) <= 2 { + local = "**" + } else { + local = string(local[0]) + "***" + string(local[len(local)-1]) + } + if len(domain) <= 2 { + domain = "***" + } else { + domain = string(domain[0]) + "***" + string(domain[len(domain)-1]) + } + return local + "@" + domain +} + +// @title X-Agents API +// @version 1.0 +// @description X-Agents 后端 API 文档 +// @termsOfService http://swagger.io/terms/ + +// @contact.name API Support +// @contact.url http://www.example.com/support +// @contact.email support@example.com + +// @license.name Apache 2.0 +// @license.url http://www.apache.org/licenses/LICENSE-2.0.html + +// @host localhost:8080 +// @BasePath / + +// @securityDefinitions.apikey BearerAuth +// @in header +// @name Authorization +// @description Type "Bearer" followed by a space and JWT token. + type AuthHandler struct { authService *service.AuthService } @@ -26,7 +71,23 @@ type LoginResponse struct { User interface{} `json:"user"` } -// Login 处理登录 +// RegisterRequest 注册请求 +type RegisterRequest struct { + Username string `json:"username" binding:"required"` + Password string `json:"password" binding:"required"` + Email string `json:"email"` +} + +// @Summary 用户登录 +// @Description 用户登录并获取 JWT Token +// @Tags 认证 +// @Accept json +// @Produce json +// @Param request body LoginRequest true "登录请求" +// @Success 200 {object} LoginResponse +// @Failure 400 {object} map[string]string +// @Failure 401 {object} map[string]string +// @Router /auth/login [post] func (h *AuthHandler) Login(c *gin.Context) { var req LoginRequest if err := c.ShouldBindJSON(&req); err != nil { @@ -54,13 +115,17 @@ func (h *AuthHandler) Login(c *gin.Context) { }) } -// Register 处理注册 +// @Summary 用户注册 +// @Description 新用户注册账号 +// @Tags 认证 +// @Accept json +// @Produce json +// @Param RegisterRequest body handler.RegisterRequest true "注册请求" +// @Success 201 {object} map[string]interface{} +// @Failure 400 {object} map[string]string +// @Router /auth/register [post] func (h *AuthHandler) Register(c *gin.Context) { - var req struct { - Username string `json:"username" binding:"required"` - Password string `json:"password" binding:"required"` - Email string `json:"email"` - } + var req RegisterRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return @@ -75,11 +140,19 @@ func (h *AuthHandler) Register(c *gin.Context) { c.JSON(http.StatusCreated, gin.H{ "id": user.ID, "username": user.Username, - "email": user.Email, + "email": maskEmail(user.Email), }) } -// GetCurrentUser 获取当前登录用户信息 +// @Summary 获取当前用户信息 +// @Description 获取已登录用户的详细信息 +// @Tags 认证 +// @Accept json +// @Produce json +// @Security BearerAuth +// @Success 200 {object} map[string]interface{} +// @Failure 401 {object} map[string]string +// @Router /auth/me [get] func (h *AuthHandler) GetCurrentUser(c *gin.Context) { userID, exists := c.Get("user_id") if !exists { @@ -96,9 +169,73 @@ func (h *AuthHandler) GetCurrentUser(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "id": user.ID, "username": user.Username, - "email": user.Email, + "email": maskEmail(user.Email), "role_id": user.RoleID, "is_active": user.IsActive, "created_at": user.CreatedAt, }) } + +// @Summary 获取所有用户 +// @Description 获取所有用户列表(需要管理员权限) +// @Tags 用户管理 +// @Accept json +// @Produce json +// @Security BearerAuth +// @Success 200 {object} map[string]interface{} +// @Failure 401 {object} map[string]string +// @Router /user/list [get] +func (h *AuthHandler) ListUsers(c *gin.Context) { + users, err := h.authService.GetAllUsers() + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + var userList []gin.H + for _, user := range users { + userList = append(userList, gin.H{ + "id": user.ID, + "username": user.Username, + "email": maskEmail(user.Email), + "role_id": user.RoleID, + "is_active": user.IsActive, + "created_at": user.CreatedAt, + }) + } + + c.JSON(http.StatusOK, gin.H{"list": userList}) +} + +// @Summary 获取用户详情 +// @Description 根据ID获取用户详情 +// @Tags 用户管理 +// @Accept json +// @Produce json +// @Security BearerAuth +// @Param id path string true "用户ID" +// @Success 200 {object} map[string]interface{} +// @Failure 404 {object} map[string]string +// @Router /user/{id} [get] +func (h *AuthHandler) GetUserByID(c *gin.Context) { + id := c.Param("id") + if id == "" { + c.JSON(http.StatusBadRequest, gin.H{"error": "user id is required"}) + return + } + + user, err := h.authService.GetUserByID(id) + if err != nil { + c.JSON(http.StatusNotFound, gin.H{"error": "user not found"}) + return + } + + c.JSON(http.StatusOK, gin.H{ + "id": user.ID, + "username": user.Username, + "email": maskEmail(user.Email), + "role_id": user.RoleID, + "is_active": user.IsActive, + "created_at": user.CreatedAt, + }) +} diff --git a/server/internal/handler/tool_handler.go b/server/internal/handler/tool_handler.go new file mode 100644 index 0000000..e102c81 --- /dev/null +++ b/server/internal/handler/tool_handler.go @@ -0,0 +1,166 @@ +package handler + +import ( + "net/http" + + "x-agents/server/internal/model" + "x-agents/server/internal/service" + + "github.com/gin-gonic/gin" +) + +// ToolHandler 工具处理器 +type ToolHandler struct { + toolService *service.ToolService +} + +// NewToolHandler 创建工具处理器 +func NewToolHandler(toolService *service.ToolService) *ToolHandler { + return &ToolHandler{toolService: toolService} +} + +// List 获取工具列表 +// @Summary 获取工具列表 +// @Description 获取所有工具列表,支持按分类和状态筛选 +// @Tags 工具管理 +// @Accept json +// @Produce json +// @Param category query string false "工具分类" +// @Param status query string false "工具状态" +// @Success 200 {object} map[string]interface{} +// @Router /tool/list [get] +func (h *ToolHandler) List(c *gin.Context) { + category := c.Query("category") + status := c.Query("status") + + tools, err := h.toolService.GetTools(category, status) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{"list": tools, "total": len(tools)}) +} + +// Sync 手动同步工具 +// @Summary 手动同步工具 +// @Description 从代码中的默认配置同步工具到数据库 +// @Tags 工具管理 +// @Accept json +// @Produce json +// @Success 200 {object} map[string]interface{} +// @Router /tool/sync [get] +func (h *ToolHandler) Sync(c *gin.Context) { + if err := h.toolService.InitDefaultTools(); err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + tools, _ := h.toolService.GetTools("", "") + c.JSON(http.StatusOK, gin.H{"message": "tools synced", "count": len(tools)}) +} + +// GetByID 根据ID获取工具 +// @Summary 获取工具详情 +// @Description 根据ID获取工具详情 +// @Tags 工具管理 +// @Accept json +// @Produce json +// @Param id path string true "工具ID" +// @Success 200 {object} map[string]interface{} +// @Router /tool/{id} [get] +func (h *ToolHandler) GetByID(c *gin.Context) { + id := c.Param("id") + if id == "" { + c.JSON(http.StatusBadRequest, gin.H{"error": "tool id is required"}) + return + } + + tool, err := h.toolService.GetToolByID(id) + if err != nil { + c.JSON(http.StatusNotFound, gin.H{"error": "tool not found"}) + return + } + + c.JSON(http.StatusOK, gin.H{"tool": tool}) +} + +// Create 创建工具 +// @Summary 创建工具 +// @Description 创建新的工具 +// @Tags 工具管理 +// @Accept json +// @Produce json +// @Param tool body model.Tool true "工具信息" +// @Success 200 {object} map[string]interface{} +// @Router /tool/add [post] +func (h *ToolHandler) Create(c *gin.Context) { + var tool model.Tool + if err := c.ShouldBindJSON(&tool); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + if err := h.toolService.CreateTool(&tool); err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{"message": "tool created", "tool": tool}) +} + +// Update 更新工具 +// @Summary 更新工具 +// @Description 更新工具信息 +// @Tags 工具管理 +// @Accept json +// @Produce json +// @Param id path string true "工具ID" +// @Param tool body model.Tool true "工具信息" +// @Success 200 {object} map[string]interface{} +// @Router /tool/{id} [put] +func (h *ToolHandler) Update(c *gin.Context) { + id := c.Param("id") + if id == "" { + c.JSON(http.StatusBadRequest, gin.H{"error": "tool id is required"}) + return + } + + var tool model.Tool + if err := c.ShouldBindJSON(&tool); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + return + } + + tool.ID = id + if err := h.toolService.UpdateTool(&tool); err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{"message": "tool updated"}) +} + +// Delete 删除工具 +// @Summary 删除工具 +// @Description 删除工具 +// @Tags 工具管理 +// @Accept json +// @Produce json +// @Param id path string true "工具ID" +// @Success 200 {object} map[string]interface{} +// @Router /tool/{id} [delete] +func (h *ToolHandler) Delete(c *gin.Context) { + id := c.Param("id") + if id == "" { + c.JSON(http.StatusBadRequest, gin.H{"error": "tool id is required"}) + return + } + + if err := h.toolService.DeleteTool(id); err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + return + } + + c.JSON(http.StatusOK, gin.H{"message": "tool deleted"}) +} diff --git a/server/internal/model/tool.go b/server/internal/model/tool.go new file mode 100644 index 0000000..e55ee5a --- /dev/null +++ b/server/internal/model/tool.go @@ -0,0 +1,31 @@ +package model + +import ( + "time" + + "github.com/google/uuid" + "gorm.io/gorm" +) + +// Tool 工具 +type Tool struct { + ID string `json:"id" gorm:"primaryKey"` + Name string `json:"name" gorm:"uniqueIndex;size:100;not null"` + Description string `json:"description" gorm:"type:text"` + Category string `json:"category" gorm:"size:50;not null"` + Provider string `json:"provider" gorm:"size:100"` + SecurityLevel string `json:"security_level" gorm:"size:20;default:'safe'"` + RequireApproval bool `json:"require_approval" gorm:"default:false"` + Parameters string `json:"parameters" gorm:"type:text"` // JSON格式存储 + Status string `json:"status" gorm:"size:20;default:'active'"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +// BeforeCreate 创建前自动生成ID +func (t *Tool) BeforeCreate(tx *gorm.DB) error { + if t.ID == "" { + t.ID = uuid.New().String() + } + return nil +} diff --git a/server/internal/model/user.go b/server/internal/model/user.go index 4d37dc5..54325cf 100644 --- a/server/internal/model/user.go +++ b/server/internal/model/user.go @@ -1,6 +1,7 @@ package model import ( + "encoding/json" "time" ) @@ -16,11 +17,11 @@ const ( // Role 角色 type Role struct { - ID string `json:"id" gorm:"primaryKey"` - Name string `json:"name" gorm:"uniqueIndex"` - Permissions []PermissionLevel `json:"permissions" gorm:"type:int[]"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ID string `json:"id" gorm:"primaryKey"` + Name string `json:"name" gorm:"uniqueIndex"` + Permissions string `json:"permissions" gorm:"type:text"` // 存储 JSON 格式的权限数组 + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } // User 用户 @@ -41,8 +42,13 @@ func (u *User) HasPermission(level PermissionLevel) bool { if u.Role == nil { return false } - for _, p := range u.Role.Permissions { - if p >= level { + // 解析 JSON 格式的权限 + var perms []int + if err := json.Unmarshal([]byte(u.Role.Permissions), &perms); err != nil { + return false + } + for _, p := range perms { + if PermissionLevel(p) >= level { return true } } diff --git a/server/internal/repository/tool_repo.go b/server/internal/repository/tool_repo.go new file mode 100644 index 0000000..eb48d80 --- /dev/null +++ b/server/internal/repository/tool_repo.go @@ -0,0 +1,83 @@ +package repository + +import ( + "x-agents/server/internal/model" + + "gorm.io/gorm" +) + +type ToolRepository struct { + db *gorm.DB +} + +func NewToolRepository(db *gorm.DB) *ToolRepository { + return &ToolRepository{db: db} +} + +// DB 获取数据库连接 +func (r *ToolRepository) DB() *gorm.DB { + return r.db +} + +func (r *ToolRepository) Create(tool *model.Tool) error { + return r.db.Create(tool).Error +} + +func (r *ToolRepository) FindAll() ([]model.Tool, error) { + var tools []model.Tool + err := r.db.Order("category, name").Find(&tools).Error + return tools, err +} + +func (r *ToolRepository) FindByCategory(category string) ([]model.Tool, error) { + var tools []model.Tool + err := r.db.Where("category = ?", category).Order("name").Find(&tools).Error + return tools, err +} + +func (r *ToolRepository) FindByID(id string) (*model.Tool, error) { + var tool model.Tool + err := r.db.First(&tool, "id = ?", id).Error + if err != nil { + return nil, err + } + return &tool, nil +} + +func (r *ToolRepository) Update(tool *model.Tool) error { + return r.db.Save(tool).Error +} + +func (r *ToolRepository) Delete(id string) error { + return r.db.Delete(&model.Tool{}, "id = ?", id).Error +} + +func (r *ToolRepository) Count() (int64, error) { + var count int64 + err := r.db.Model(&model.Tool{}).Count(&count).Error + return count, err +} + +// UpsertBatch 批量upsert工具 +func (r *ToolRepository) UpsertBatch(tools []model.Tool) error { + for _, tool := range tools { + var existing model.Tool + err := r.db.First(&existing, "name = ?", tool.Name).Error + if err == gorm.ErrRecordNotFound { + if err := r.db.Create(&tool).Error; err != nil { + return err + } + } else if err != nil { + return err + } else { + existing.Description = tool.Description + existing.Category = tool.Category + existing.Provider = tool.Provider + existing.Status = tool.Status + if err := r.db.Save(&existing).Error; err != nil { + return err + } + } + } + return nil +} diff --git a/server/internal/service/auth_service.go b/server/internal/service/auth_service.go index e8d1655..71930d8 100644 --- a/server/internal/service/auth_service.go +++ b/server/internal/service/auth_service.go @@ -1,7 +1,12 @@ package service import ( + "encoding/json" "errors" + "log" + "os" + "path/filepath" + "strings" "time" "x-agents/server/internal/model" @@ -123,10 +128,11 @@ func (s *AuthService) Register(username, password, email string) (*model.User, e role, err := s.userRepo.FindRoleByID(user.RoleID) if err != nil { // 创建默认角色 + perms, _ := json.Marshal([]int{int(model.PermissionRead), int(model.PermissionWrite)}) role = &model.Role{ ID: "user", Name: "user", - Permissions: []model.PermissionLevel{model.PermissionRead, model.PermissionWrite}, + Permissions: string(perms), } s.userRepo.CreateRole(role) user.Role = role @@ -136,10 +142,74 @@ func (s *AuthService) Register(username, password, email string) (*model.User, e return nil, err } + // 创建用户工作空间目录 + if err := s.createUserWorkspace(username); err != nil { + // 工作空间创建失败不影响注册成功,仅记录日志 + println("Warning: failed to create user workspace:", err.Error()) + } + return user, nil } +// createUserWorkspace 创建用户工作空间目录 +func (s *AuthService) createUserWorkspace(username string) error { + // 获取当前可执行文件所在目录 + execPath, err := os.Getwd() + if err != nil { + return err + } + + // 尝试多种方式获取项目根目录 + projectRoot := execPath + + // 方式1: 如果当前目录名为 server,向上找一级 + baseName := filepath.Base(execPath) + // 处理 Windows 和 Unix 风格路径 + if baseName == "server" || strings.HasSuffix(execPath, "/server") || strings.HasSuffix(execPath, "\\server") { + projectRoot = filepath.Dir(execPath) + } + + // 方式2: 尝试向上查找包含 .git 或 package.json 的目录 + if _, err := os.Stat(filepath.Join(projectRoot, ".git")); os.IsNotExist(err) { + // 继续向上查找 + for i := 0; i < 3; i++ { + parent := filepath.Dir(projectRoot) + if parent == projectRoot { + break + } + if _, err := os.Stat(filepath.Join(parent, ".git")); err == nil { + projectRoot = parent + break + } + projectRoot = parent + } + } + + log.Printf("[Workspace] Creating workspace at: %s", filepath.Join(projectRoot, "account", username)) + + // 创建 account 目录和用户目录 + workspacePath := filepath.Join(projectRoot, "account", username) + if err := os.MkdirAll(workspacePath, 0755); err != nil { + return err + } + + // 创建子目录 + subDirs := []string{"projects", "files", "temp"} + for _, dir := range subDirs { + if err := os.MkdirAll(filepath.Join(workspacePath, dir), 0755); err != nil { + return err + } + } + + return nil +} + // GetUserByID 根据ID获取用户 func (s *AuthService) GetUserByID(id string) (*model.User, error) { return s.userRepo.FindByID(id) } + +// GetAllUsers 获取所有用户 +func (s *AuthService) GetAllUsers() ([]model.User, error) { + return s.userRepo.FindAll() +} diff --git a/server/internal/service/tool_service.go b/server/internal/service/tool_service.go new file mode 100644 index 0000000..b0be55f --- /dev/null +++ b/server/internal/service/tool_service.go @@ -0,0 +1,219 @@ +package service + +import ( + "log" + "x-agents/server/internal/model" + "x-agents/server/internal/repository" +) + +type ToolService struct { + toolRepo *repository.ToolRepository +} + +func NewToolService(toolRepo *repository.ToolRepository) *ToolService { + return &ToolService{toolRepo: toolRepo} +} + +func (s *ToolService) GetAllTools() ([]model.Tool, error) { + return s.toolRepo.FindAll() +} + +func (s *ToolService) GetToolsByCategory(category string) ([]model.Tool, error) { + return s.toolRepo.FindByCategory(category) +} + +func (s *ToolService) GetToolByID(id string) (*model.Tool, error) { + return s.toolRepo.FindByID(id) +} + +// GetTools 根据条件获取工具列表 +func (s *ToolService) GetTools(category string, status string) ([]model.Tool, error) { + var tools []model.Tool + query := s.toolRepo.DB() + + if category != "" { + query = query.Where("category = ?", category) + } + if status != "" { + query = query.Where("status = ?", status) + } + + err := query.Find(&tools).Error + return tools, err +} + +func (s *ToolService) CreateTool(tool *model.Tool) error { + return s.toolRepo.Create(tool) +} + +func (s *ToolService) UpdateTool(tool *model.Tool) error { + return s.toolRepo.Update(tool) +} + +func (s *ToolService) DeleteTool(id string) error { + return s.toolRepo.Delete(id) +} + +// InitDefaultTools 初始化默认工具到数据库 +func (s *ToolService) InitDefaultTools() error { + log.Println("[ToolService] Starting init default tools...") + + // 获取默认工具 + tools := s.getDefaultTools() + + // 删除现有的系统工具,重新插入 + s.toolRepo.DB().Where("provider = ?", "system").Delete(&model.Tool{}) + log.Printf("[ToolService] Deleted existing system tools, inserting %d default tools...", len(tools)) + + for _, tool := range tools { + if err := s.toolRepo.Create(&tool); err != nil { + log.Printf("[ToolService] Create tool error: %v", err) + return err + } + } + + log.Printf("[ToolService] Default tools initialized successfully") + return nil +} + +// getDefaultTools 获取默认工具列表 +func (s *ToolService) getDefaultTools() []model.Tool { + return []model.Tool{ + // 文件操作 + { + Name: "read_file", + Description: "Read the contents of a file from the filesystem.", + Category: "file", + SecurityLevel: "safe", + RequireApproval: false, + Provider: "system", + Status: "active", + Parameters: `{"type":"object","properties":{"file_path":{"type":"string","description":"The path to the file to read"},"encoding":{"type":"string","description":"File encoding (default: utf-8)","default":"utf-8"}},"required":["file_path"]}`, + }, + { + Name: "write_file", + Description: "Write content to a file. Creates the file if it doesn't exist, overwrites if it does.", + Category: "file", + SecurityLevel: "review", + RequireApproval: true, + Provider: "system", + Status: "active", + Parameters: `{"type":"object","properties":{"file_path":{"type":"string","description":"The path to the file to write"},"content":{"type":"string","description":"The content to write to the file"}},"required":["file_path","content"]}`, + }, + { + Name: "list_dir", + Description: "List the contents of a directory.", + Category: "file", + SecurityLevel: "safe", + RequireApproval: false, + Provider: "system", + Status: "active", + Parameters: `{"type":"object","properties":{"dir_path":{"type":"string","description":"The path to the directory to list","default":"."}}}`, + }, + { + Name: "delete_file", + Description: "Delete a file or directory.", + Category: "file", + SecurityLevel: "danger", + RequireApproval: true, + Provider: "system", + Status: "active", + Parameters: `{"type":"object","properties":{"file_path":{"type":"string","description":"The path to the file or directory to delete"}},"required":["file_path"]}`, + }, + { + Name: "search_files", + Description: "Search for files by name pattern or content.", + Category: "file", + SecurityLevel: "safe", + RequireApproval: false, + Provider: "system", + Status: "active", + Parameters: `{"type":"object","properties":{"directory":{"type":"string","description":"The directory to search in"},"pattern":{"type":"string","description":"Glob pattern for file names","default":"*"},"content_pattern":{"type":"string","description":"Search for files containing this text"}},"required":["directory"]}`, + }, + // 代码执行 + { + Name: "execute_python", + Description: "Execute Python code in a sandboxed environment.", + Category: "executor", + SecurityLevel: "review", + RequireApproval: true, + Provider: "system", + Status: "active", + Parameters: `{"type":"object","properties":{"code":{"type":"string","description":"The Python code to execute"},"timeout":{"type":"integer","description":"Execution timeout in seconds","default":30}},"required":["code"]}`, + }, + { + Name: "execute_javascript", + Description: "Execute JavaScript code in a sandboxed environment.", + Category: "executor", + SecurityLevel: "review", + RequireApproval: true, + Provider: "system", + Status: "active", + Parameters: `{"type":"object","properties":{"code":{"type":"string","description":"The JavaScript code to execute"},"timeout":{"type":"integer","description":"Execution timeout in seconds","default":30}},"required":["code"]}`, + }, + { + Name: "execute_bash", + Description: "Execute a bash command in a sandboxed environment.", + Category: "executor", + SecurityLevel: "danger", + RequireApproval: true, + Provider: "system", + Status: "active", + Parameters: `{"type":"object","properties":{"command":{"type":"string","description":"The bash command to execute"},"timeout":{"type":"integer","description":"Execution timeout in seconds","default":30}},"required":["command"]}`, + }, + // 网页 + { + Name: "web_fetch", + Description: "Fetch content from a web URL.", + Category: "web", + SecurityLevel: "safe", + RequireApproval: false, + Provider: "system", + Status: "active", + Parameters: `{"type":"object","properties":{"url":{"type":"string","description":"The URL to fetch"},"method":{"type":"string","description":"HTTP method","default":"GET"},"timeout":{"type":"integer","description":"Request timeout in seconds","default":30}},"required":["url"]}`, + }, + { + Name: "web_search", + Description: "Search the web for information.", + Category: "web", + SecurityLevel: "safe", + RequireApproval: false, + Provider: "system", + Status: "active", + Parameters: `{"type":"object","properties":{"query":{"type":"string","description":"The search query"},"max_results":{"type":"integer","description":"Maximum number of results","default":5}},"required":["query"]}`, + }, + // HTTP + { + Name: "http_request", + Description: "Make HTTP requests to APIs.", + Category: "http", + SecurityLevel: "safe", + RequireApproval: false, + Provider: "system", + Status: "active", + Parameters: `{"type":"object","properties":{"url":{"type":"string","description":"The URL to request"},"method":{"type":"string","description":"HTTP method","default":"GET"},"params":{"type":"object","description":"Query parameters"},"json_data":{"type":"object","description":"JSON body"},"timeout":{"type":"integer","description":"Request timeout","default":30}},"required":["url"]}`, + }, + // 通知 + { + Name: "send_notification", + Description: "Send notifications via email, webhook, dingtalk, or slack.", + Category: "notification", + SecurityLevel: "safe", + RequireApproval: false, + Provider: "system", + Status: "active", + Parameters: `{"type":"object","properties":{"type":{"type":"string","description":"Notification type: email, webhook, dingtalk, slack"},"message":{"type":"string","description":"The notification message"}},"required":["type","message"]}`, + }, + // 系统 + { + Name: "get_current_time", + Description: "Get the current date and time.", + Category: "system", + SecurityLevel: "safe", + RequireApproval: false, + Provider: "system", + Status: "active", + Parameters: `{"type":"object","properties":{"timezone":{"type":"string","description":"Optional timezone (e.g., UTC, Asia/Shanghai)"}}}`, + }, + } +}