From 9fec4ecdb568935678e0c2cd765aa1e570923302 Mon Sep 17 00:00:00 2001 From: engigu Date: Thu, 5 Mar 2026 20:19:35 +0800 Subject: [PATCH] feat: add openapi --- Makefile | 5 + configs/config.example.ini | 26 +- docs/docs.go | 1157 +++++++++++++++++++++++ docs/swagger.json | 1133 ++++++++++++++++++++++ docs/swagger.yaml | 684 ++++++++++++++ go.mod | 68 +- go.sum | 123 +++ internal/controllers/env_controller.go | 77 ++ internal/controllers/log_controller.go | 47 + internal/controllers/task_controller.go | 60 ++ internal/middleware/auth.go | 23 + internal/router/router.go | 5 + internal/services/config_service.go | 22 + internal/utils/pagination.go | 18 +- main.go | 21 + 15 files changed, 3447 insertions(+), 22 deletions(-) create mode 100644 docs/docs.go create mode 100644 docs/swagger.json create mode 100644 docs/swagger.yaml diff --git a/Makefile b/Makefile index 6482bc0..33da66a 100644 --- a/Makefile +++ b/Makefile @@ -109,6 +109,10 @@ agent-run: deps: $(GOMOD) tidy +# Generate swagger documentation +swag: + go run github.com/swaggo/swag/cmd/swag@latest init -g main.go -o ./docs + # Docker build docker-build: docker build -t baihu:dev -f docker/Dockerfile . @@ -165,4 +169,5 @@ help: @echo " docker-dev-d - Start isolated Docker dev environment (background)" @echo " docker-dev-down - Stop Docker dev environment (keep caches)" @echo " docker-dev-clean - Stop and clean Docker dev environment (remove caches)" + @echo " swag - Generate swagger documentation" @echo " help - Show this help message" diff --git a/configs/config.example.ini b/configs/config.example.ini index a81e66e..c0880d9 100644 --- a/configs/config.example.ini +++ b/configs/config.example.ini @@ -1,15 +1,39 @@ [server] +# 服务监听端口 port = 8052 +# 服务监听地址 host = 0.0.0.0 # URL前缀,例如 /baihu,留空则无前缀 # 配置后:前端路径为 /baihu/*,后端API路径为 /baihu/api/v1/* url_prefix = [database] +# 数据库类型: sqlite, mysql, postgres type = sqlite +# 数据库连接地址 (mysql/postgres) host = localhost +# 数据库连接端口 (mysql: 3306, postgres: 5432) port = 3306 +# 数据库用户名 user = root +# 数据库密码 password = -dbname = ql_panel +# 数据库名称 +dbname = baihu +# 数据库文件路径 (仅 sqlite) +path = data/baihu.db +# 表前缀 table_prefix = baihu_ + +[security] +# JWT 密钥。留空则在首次启动时自动生成并保存到数据库设置中。 +# 如果你手动设置了此项,它将覆盖数据库中的设置。 +secret = + +[swagger] +# 是否开启 Swagger API 文档 (开发测试建议开启,生产环境建议关闭或设置强密码) +enabled = true +# Swagger 文档 Basic Auth 账号 +user = admin +# Swagger 文档 Basic Auth 密码 +password = swagger_password diff --git a/docs/docs.go b/docs/docs.go new file mode 100644 index 0000000..702c651 --- /dev/null +++ b/docs/docs.go @@ -0,0 +1,1157 @@ +// 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}}", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "name": "API Support", + "url": "http://www.swagger.io/support", + "email": "support@swagger.io" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + }, + "version": "{{.Version}}" + }, + "host": "{{.Host}}", + "basePath": "{{.BasePath}}", + "paths": { + "/env": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "分页获取环境变量列表,支持按名称筛选", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "环境变量" + ], + "summary": "获取环境变量列表", + "parameters": [ + { + "type": "string", + "description": "按名称模糊查询", + "name": "name", + "in": "query" + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页数量", + "name": "page_size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "allOf": [ + { + "$ref": "#/definitions/utils.PaginationData" + }, + { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/vo.EnvVO" + } + } + } + } + ] + } + } + } + ] + } + } + } + }, + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "创建新的环境变量", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "环境变量" + ], + "summary": "创建环境变量", + "parameters": [ + { + "description": "环境变量信息", + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/vo.EnvVO" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + } + }, + "/env/all": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取当前用户的所有环境变量(不分页)", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "环境变量" + ], + "summary": "获取所有环境变量", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/vo.EnvVO" + } + } + } + } + ] + } + } + } + } + }, + "/env/{id}": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "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": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/vo.EnvVO" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "根据 ID 更新环境变量信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "环境变量" + ], + "summary": "更新环境变量", + "parameters": [ + { + "type": "string", + "description": "环境变量ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/vo.EnvVO" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + }, + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "根据 ID 删除环境变量,支持强制删除", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "环境变量" + ], + "summary": "删除环境变量", + "parameters": [ + { + "type": "string", + "description": "环境变量ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "是否强制删除", + "name": "force", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + }, + "409": { + "description": "引用冲突", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/vo.TaskVO" + } + } + } + } + ] + } + } + } + } + }, + "/env/{id}/tasks": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "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": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/vo.TaskVO" + } + } + } + } + ] + } + } + } + } + }, + "/logs": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "分页获取任务日志列表,支持按任务 ID、任务名称、状态筛选", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "日志" + ], + "summary": "获取任务日志列表", + "parameters": [ + { + "type": "string", + "description": "任务 ID", + "name": "task_id", + "in": "query" + }, + { + "type": "string", + "description": "任务名称", + "name": "task_name", + "in": "query" + }, + { + "type": "string", + "description": "状态", + "name": "status", + "in": "query" + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页数量", + "name": "page_size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "allOf": [ + { + "$ref": "#/definitions/utils.PaginationData" + }, + { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/vo.TaskLogVO" + } + } + } + } + ] + } + } + } + ] + } + } + } + } + }, + "/logs/clear": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "清空所有日志或指定任务的日志", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "日志" + ], + "summary": "清空日志", + "parameters": [ + { + "description": "清空范围信息", + "name": "body", + "in": "body", + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + } + }, + "/logs/{id}": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "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": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/vo.TaskLogVO" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + }, + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "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/github_com_engigu_baihu-panel_internal_utils.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + } + }, + "/tasks": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "分页获取任务列表,支持按名称、Agent ID、标签、类型筛选", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "任务" + ], + "summary": "获取任务列表", + "parameters": [ + { + "type": "string", + "description": "任务名称", + "name": "name", + "in": "query" + }, + { + "type": "string", + "description": "Agent ID", + "name": "agent_id", + "in": "query" + }, + { + "type": "string", + "description": "标签", + "name": "tags", + "in": "query" + }, + { + "type": "string", + "description": "任务类型", + "name": "type", + "in": "query" + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页数量", + "name": "page_size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "allOf": [ + { + "$ref": "#/definitions/utils.PaginationData" + }, + { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/vo.TaskVO" + } + } + } + } + ] + } + } + } + ] + } + } + } + } + }, + "/tasks/stop/{logID}": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "根据运行日志 ID 停止正在执行的任务", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "任务" + ], + "summary": "停止任务", + "parameters": [ + { + "type": "string", + "description": "运行日志ID", + "name": "logID", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + } + }, + "/tasks/{id}": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "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": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/vo.TaskVO" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "根据 ID 更新任务信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "任务" + ], + "summary": "更新任务", + "parameters": [ + { + "type": "string", + "description": "任务ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "任务更新信息", + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/vo.TaskVO" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + }, + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "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/github_com_engigu_baihu-panel_internal_utils.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + } + } + }, + "definitions": { + "github_com_engigu_baihu-panel_internal_utils.Response": { + "type": "object", + "properties": { + "code": { + "type": "integer" + }, + "data": {}, + "msg": { + "type": "string" + } + } + }, + "utils.PaginationData": { + "type": "object", + "properties": { + "list": {}, + "page": { + "type": "integer" + }, + "page_size": { + "type": "integer" + }, + "total": { + "type": "integer" + } + } + }, + "vo.EnvVO": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "remark": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "vo.TaskLogVO": { + "type": "object", + "properties": { + "agent_id": { + "type": "string" + }, + "command": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "duration": { + "type": "integer" + }, + "end_time": { + "type": "string" + }, + "error": { + "type": "string" + }, + "exit_code": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "output": { + "type": "string" + }, + "start_time": { + "type": "string" + }, + "status": { + "type": "string" + }, + "task_id": { + "type": "string" + }, + "task_name": { + "type": "string" + }, + "task_type": { + "type": "string" + } + } + }, + "vo.TaskVO": { + "type": "object", + "properties": { + "agent_id": { + "type": "string" + }, + "clean_config": { + "type": "string" + }, + "command": { + "type": "string" + }, + "config": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "envs": { + "type": "string" + }, + "id": { + "type": "string" + }, + "languages": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "last_run": { + "type": "string" + }, + "name": { + "type": "string" + }, + "next_run": { + "type": "string" + }, + "random_range": { + "type": "integer" + }, + "retry_count": { + "type": "integer" + }, + "retry_interval": { + "type": "integer" + }, + "schedule": { + "type": "string" + }, + "tags": { + "type": "string" + }, + "timeout": { + "type": "integer" + }, + "trigger_type": { + "type": "string" + }, + "type": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "work_dir": { + "type": "string" + } + } + } + }, + "securityDefinitions": { + "ApiKeyAuth": { + "type": "apiKey", + "name": "Authorization", + "in": "header" + } + } +}` + +// SwaggerInfo holds exported Swagger Info so clients can modify it +var SwaggerInfo = &swag.Spec{ + Version: "1.0", + Host: "localhost:8052", + BasePath: "/api/v1", + Schemes: []string{}, + Title: "Baihu Panel API", + Description: "Baihu Panel API Server documentation.", + InfoInstanceName: "swagger", + SwaggerTemplate: docTemplate, + LeftDelim: "{{", + RightDelim: "}}", +} + +func init() { + swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) +} diff --git a/docs/swagger.json b/docs/swagger.json new file mode 100644 index 0000000..029ef02 --- /dev/null +++ b/docs/swagger.json @@ -0,0 +1,1133 @@ +{ + "swagger": "2.0", + "info": { + "description": "Baihu Panel API Server documentation.", + "title": "Baihu Panel API", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "name": "API Support", + "url": "http://www.swagger.io/support", + "email": "support@swagger.io" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + }, + "version": "1.0" + }, + "host": "localhost:8052", + "basePath": "/api/v1", + "paths": { + "/env": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "分页获取环境变量列表,支持按名称筛选", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "环境变量" + ], + "summary": "获取环境变量列表", + "parameters": [ + { + "type": "string", + "description": "按名称模糊查询", + "name": "name", + "in": "query" + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页数量", + "name": "page_size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "allOf": [ + { + "$ref": "#/definitions/utils.PaginationData" + }, + { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/vo.EnvVO" + } + } + } + } + ] + } + } + } + ] + } + } + } + }, + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "创建新的环境变量", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "环境变量" + ], + "summary": "创建环境变量", + "parameters": [ + { + "description": "环境变量信息", + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/vo.EnvVO" + } + } + } + ] + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + } + }, + "/env/all": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "获取当前用户的所有环境变量(不分页)", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "环境变量" + ], + "summary": "获取所有环境变量", + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/vo.EnvVO" + } + } + } + } + ] + } + } + } + } + }, + "/env/{id}": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "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": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/vo.EnvVO" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "根据 ID 更新环境变量信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "环境变量" + ], + "summary": "更新环境变量", + "parameters": [ + { + "type": "string", + "description": "环境变量ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "更新信息", + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/vo.EnvVO" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + }, + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "根据 ID 删除环境变量,支持强制删除", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "环境变量" + ], + "summary": "删除环境变量", + "parameters": [ + { + "type": "string", + "description": "环境变量ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "是否强制删除", + "name": "force", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + }, + "409": { + "description": "引用冲突", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/vo.TaskVO" + } + } + } + } + ] + } + } + } + } + }, + "/env/{id}/tasks": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "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": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/vo.TaskVO" + } + } + } + } + ] + } + } + } + } + }, + "/logs": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "分页获取任务日志列表,支持按任务 ID、任务名称、状态筛选", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "日志" + ], + "summary": "获取任务日志列表", + "parameters": [ + { + "type": "string", + "description": "任务 ID", + "name": "task_id", + "in": "query" + }, + { + "type": "string", + "description": "任务名称", + "name": "task_name", + "in": "query" + }, + { + "type": "string", + "description": "状态", + "name": "status", + "in": "query" + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页数量", + "name": "page_size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "allOf": [ + { + "$ref": "#/definitions/utils.PaginationData" + }, + { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/vo.TaskLogVO" + } + } + } + } + ] + } + } + } + ] + } + } + } + } + }, + "/logs/clear": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "清空所有日志或指定任务的日志", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "日志" + ], + "summary": "清空日志", + "parameters": [ + { + "description": "清空范围信息", + "name": "body", + "in": "body", + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + } + }, + "/logs/{id}": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "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": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/vo.TaskLogVO" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + }, + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "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/github_com_engigu_baihu-panel_internal_utils.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + } + }, + "/tasks": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "分页获取任务列表,支持按名称、Agent ID、标签、类型筛选", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "任务" + ], + "summary": "获取任务列表", + "parameters": [ + { + "type": "string", + "description": "任务名称", + "name": "name", + "in": "query" + }, + { + "type": "string", + "description": "Agent ID", + "name": "agent_id", + "in": "query" + }, + { + "type": "string", + "description": "标签", + "name": "tags", + "in": "query" + }, + { + "type": "string", + "description": "任务类型", + "name": "type", + "in": "query" + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页数量", + "name": "page_size", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "allOf": [ + { + "$ref": "#/definitions/utils.PaginationData" + }, + { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/vo.TaskVO" + } + } + } + } + ] + } + } + } + ] + } + } + } + } + }, + "/tasks/stop/{logID}": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "根据运行日志 ID 停止正在执行的任务", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "任务" + ], + "summary": "停止任务", + "parameters": [ + { + "type": "string", + "description": "运行日志ID", + "name": "logID", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + } + }, + "/tasks/{id}": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "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": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/vo.TaskVO" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + }, + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "根据 ID 更新任务信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "任务" + ], + "summary": "更新任务", + "parameters": [ + { + "type": "string", + "description": "任务ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "任务更新信息", + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/vo.TaskVO" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + }, + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "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/github_com_engigu_baihu-panel_internal_utils.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/github_com_engigu_baihu-panel_internal_utils.Response" + } + } + } + } + } + }, + "definitions": { + "github_com_engigu_baihu-panel_internal_utils.Response": { + "type": "object", + "properties": { + "code": { + "type": "integer" + }, + "data": {}, + "msg": { + "type": "string" + } + } + }, + "utils.PaginationData": { + "type": "object", + "properties": { + "list": {}, + "page": { + "type": "integer" + }, + "page_size": { + "type": "integer" + }, + "total": { + "type": "integer" + } + } + }, + "vo.EnvVO": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "hidden": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "remark": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "vo.TaskLogVO": { + "type": "object", + "properties": { + "agent_id": { + "type": "string" + }, + "command": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "duration": { + "type": "integer" + }, + "end_time": { + "type": "string" + }, + "error": { + "type": "string" + }, + "exit_code": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "output": { + "type": "string" + }, + "start_time": { + "type": "string" + }, + "status": { + "type": "string" + }, + "task_id": { + "type": "string" + }, + "task_name": { + "type": "string" + }, + "task_type": { + "type": "string" + } + } + }, + "vo.TaskVO": { + "type": "object", + "properties": { + "agent_id": { + "type": "string" + }, + "clean_config": { + "type": "string" + }, + "command": { + "type": "string" + }, + "config": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "envs": { + "type": "string" + }, + "id": { + "type": "string" + }, + "languages": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "last_run": { + "type": "string" + }, + "name": { + "type": "string" + }, + "next_run": { + "type": "string" + }, + "random_range": { + "type": "integer" + }, + "retry_count": { + "type": "integer" + }, + "retry_interval": { + "type": "integer" + }, + "schedule": { + "type": "string" + }, + "tags": { + "type": "string" + }, + "timeout": { + "type": "integer" + }, + "trigger_type": { + "type": "string" + }, + "type": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "work_dir": { + "type": "string" + } + } + } + }, + "securityDefinitions": { + "ApiKeyAuth": { + "type": "apiKey", + "name": "Authorization", + "in": "header" + } + } +} \ No newline at end of file diff --git a/docs/swagger.yaml b/docs/swagger.yaml new file mode 100644 index 0000000..cebc7f2 --- /dev/null +++ b/docs/swagger.yaml @@ -0,0 +1,684 @@ +basePath: /api/v1 +definitions: + github_com_engigu_baihu-panel_internal_utils.Response: + properties: + code: + type: integer + data: {} + msg: + type: string + type: object + utils.PaginationData: + properties: + list: {} + page: + type: integer + page_size: + type: integer + total: + type: integer + type: object + vo.EnvVO: + properties: + created_at: + type: string + hidden: + type: boolean + id: + type: string + name: + type: string + remark: + type: string + updated_at: + type: string + value: + type: string + type: object + vo.TaskLogVO: + properties: + agent_id: + type: string + command: + type: string + created_at: + type: string + duration: + type: integer + end_time: + type: string + error: + type: string + exit_code: + type: integer + id: + type: string + output: + type: string + start_time: + type: string + status: + type: string + task_id: + type: string + task_name: + type: string + task_type: + type: string + type: object + vo.TaskVO: + properties: + agent_id: + type: string + clean_config: + type: string + command: + type: string + config: + type: string + created_at: + type: string + enabled: + type: boolean + envs: + type: string + id: + type: string + languages: + items: + additionalProperties: + type: string + type: object + type: array + last_run: + type: string + name: + type: string + next_run: + type: string + random_range: + type: integer + retry_count: + type: integer + retry_interval: + type: integer + schedule: + type: string + tags: + type: string + timeout: + type: integer + trigger_type: + type: string + type: + type: string + updated_at: + type: string + work_dir: + type: string + type: object +host: localhost:8052 +info: + contact: + email: support@swagger.io + name: API Support + url: http://www.swagger.io/support + description: Baihu Panel API Server documentation. + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + termsOfService: http://swagger.io/terms/ + title: Baihu Panel API + version: "1.0" +paths: + /env: + get: + consumes: + - application/json + description: 分页获取环境变量列表,支持按名称筛选 + parameters: + - description: 按名称模糊查询 + in: query + name: name + type: string + - description: 页码 + in: query + name: page + type: integer + - description: 每页数量 + in: query + name: page_size + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + - properties: + data: + allOf: + - $ref: '#/definitions/utils.PaginationData' + - properties: + list: + items: + $ref: '#/definitions/vo.EnvVO' + type: array + type: object + type: object + security: + - ApiKeyAuth: [] + summary: 获取环境变量列表 + tags: + - 环境变量 + post: + consumes: + - application/json + description: 创建新的环境变量 + parameters: + - description: 环境变量信息 + in: body + name: body + required: true + schema: + type: object + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + - properties: + data: + $ref: '#/definitions/vo.EnvVO' + type: object + "400": + description: Bad Request + schema: + $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + security: + - ApiKeyAuth: [] + summary: 创建环境变量 + tags: + - 环境变量 + /env/{id}: + delete: + consumes: + - application/json + description: 根据 ID 删除环境变量,支持强制删除 + parameters: + - description: 环境变量ID + in: path + name: id + required: true + type: string + - description: 是否强制删除 + in: query + name: force + type: boolean + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + "409": + description: 引用冲突 + schema: + allOf: + - $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + - properties: + data: + items: + $ref: '#/definitions/vo.TaskVO' + type: array + type: object + security: + - ApiKeyAuth: [] + 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: + allOf: + - $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + - properties: + data: + $ref: '#/definitions/vo.EnvVO' + type: object + "404": + description: Not Found + schema: + $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + security: + - ApiKeyAuth: [] + summary: 获取环境变量详情 + tags: + - 环境变量 + put: + consumes: + - application/json + description: 根据 ID 更新环境变量信息 + parameters: + - description: 环境变量ID + in: path + name: id + required: true + type: string + - description: 更新信息 + in: body + name: body + required: true + schema: + type: object + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + - properties: + data: + $ref: '#/definitions/vo.EnvVO' + type: object + "404": + description: Not Found + schema: + $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + security: + - ApiKeyAuth: [] + summary: 更新环境变量 + tags: + - 环境变量 + /env/{id}/tasks: + get: + consumes: + - application/json + description: 获取引用了该环境变量的任务列表 + parameters: + - description: 环境变量ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + - properties: + data: + items: + $ref: '#/definitions/vo.TaskVO' + type: array + type: object + security: + - ApiKeyAuth: [] + summary: 获取关联任务 + tags: + - 环境变量 + /env/all: + get: + consumes: + - application/json + description: 获取当前用户的所有环境变量(不分页) + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + - properties: + data: + items: + $ref: '#/definitions/vo.EnvVO' + type: array + type: object + security: + - ApiKeyAuth: [] + summary: 获取所有环境变量 + tags: + - 环境变量 + /logs: + get: + consumes: + - application/json + description: 分页获取任务日志列表,支持按任务 ID、任务名称、状态筛选 + parameters: + - description: 任务 ID + in: query + name: task_id + type: string + - description: 任务名称 + in: query + name: task_name + type: string + - description: 状态 + in: query + name: status + type: string + - description: 页码 + in: query + name: page + type: integer + - description: 每页数量 + in: query + name: page_size + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + - properties: + data: + allOf: + - $ref: '#/definitions/utils.PaginationData' + - properties: + list: + items: + $ref: '#/definitions/vo.TaskLogVO' + type: array + type: object + type: object + security: + - ApiKeyAuth: [] + summary: 获取任务日志列表 + tags: + - 日志 + /logs/{id}: + delete: + 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/github_com_engigu_baihu-panel_internal_utils.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + security: + - ApiKeyAuth: [] + 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: + allOf: + - $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + - properties: + data: + $ref: '#/definitions/vo.TaskLogVO' + type: object + "404": + description: Not Found + schema: + $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + security: + - ApiKeyAuth: [] + summary: 获取日志详情 + tags: + - 日志 + /logs/clear: + post: + consumes: + - application/json + description: 清空所有日志或指定任务的日志 + parameters: + - description: 清空范围信息 + in: body + name: body + schema: + type: object + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + security: + - ApiKeyAuth: [] + summary: 清空日志 + tags: + - 日志 + /tasks: + get: + consumes: + - application/json + description: 分页获取任务列表,支持按名称、Agent ID、标签、类型筛选 + parameters: + - description: 任务名称 + in: query + name: name + type: string + - description: Agent ID + in: query + name: agent_id + type: string + - description: 标签 + in: query + name: tags + type: string + - description: 任务类型 + in: query + name: type + type: string + - description: 页码 + in: query + name: page + type: integer + - description: 每页数量 + in: query + name: page_size + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + - properties: + data: + allOf: + - $ref: '#/definitions/utils.PaginationData' + - properties: + list: + items: + $ref: '#/definitions/vo.TaskVO' + type: array + type: object + type: object + security: + - ApiKeyAuth: [] + summary: 获取任务列表 + tags: + - 任务 + /tasks/{id}: + delete: + 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/github_com_engigu_baihu-panel_internal_utils.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + security: + - ApiKeyAuth: [] + 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: + allOf: + - $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + - properties: + data: + $ref: '#/definitions/vo.TaskVO' + type: object + "404": + description: Not Found + schema: + $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + security: + - ApiKeyAuth: [] + summary: 获取任务详情 + tags: + - 任务 + put: + consumes: + - application/json + description: 根据 ID 更新任务信息 + parameters: + - description: 任务ID + in: path + name: id + required: true + type: string + - description: 任务更新信息 + in: body + name: body + required: true + schema: + type: object + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + - properties: + data: + $ref: '#/definitions/vo.TaskVO' + type: object + "404": + description: Not Found + schema: + $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + security: + - ApiKeyAuth: [] + summary: 更新任务 + tags: + - 任务 + /tasks/stop/{logID}: + post: + consumes: + - application/json + description: 根据运行日志 ID 停止正在执行的任务 + parameters: + - description: 运行日志ID + in: path + name: logID + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/github_com_engigu_baihu-panel_internal_utils.Response' + security: + - ApiKeyAuth: [] + summary: 停止任务 + tags: + - 任务 +securityDefinitions: + ApiKeyAuth: + in: header + name: Authorization + type: apiKey +swagger: "2.0" diff --git a/go.mod b/go.mod index d3e1d95..76fb329 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.25.0 require ( github.com/aliyun/alibaba-cloud-sdk-go v1.63.107 github.com/creack/pty v1.1.24 - github.com/gin-gonic/gin v1.9.1 + github.com/gin-gonic/gin v1.11.0 github.com/glebarez/sqlite v1.11.0 github.com/gofrs/flock v0.13.0 github.com/golang-jwt/jwt/v5 v5.3.0 @@ -16,8 +16,8 @@ require ( github.com/silenceper/wechat/v2 v2.1.12 github.com/sirupsen/logrus v1.9.4 go.uber.org/zap v1.27.1 - golang.org/x/net v0.47.0 - golang.org/x/text v0.32.0 + golang.org/x/net v0.51.0 + golang.org/x/text v0.34.0 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/ini.v1 v1.67.0 gopkg.in/natefinch/lumberjack.v2 v2.2.1 @@ -29,30 +29,49 @@ require ( require ( dario.cat/mergo v1.0.2 // indirect filippo.io/edwards25519 v1.1.0 // 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/air-verse/air v1.64.5 // indirect github.com/andybalholm/brotli v1.2.0 // indirect github.com/bep/godartsass/v2 v2.5.0 // indirect github.com/bep/golibsass v1.2.0 // indirect github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d // indirect - github.com/bytedance/sonic v1.9.1 // 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/cespare/xxhash/v2 v2.3.0 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // 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/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/fatih/color v1.18.0 // indirect github.com/fatih/structs v1.1.0 // indirect github.com/fsnotify/fsnotify v1.9.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/glebarez/go-sqlite v1.21.2 // 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.3 // indirect + github.com/go-openapi/swag v0.25.4 // 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.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.5 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // 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/go-playground/validator/v10 v10.30.1 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-sql-driver/mysql v1.9.3 // indirect github.com/gobwas/glob v0.2.3 // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-json v0.10.5 // indirect + github.com/goccy/go-yaml v1.19.2 // indirect github.com/gohugoio/hugo v0.149.1 // indirect github.com/google/uuid v1.6.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect @@ -63,10 +82,12 @@ require ( github.com/jinzhu/now v1.1.5 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/joho/godotenv v1.5.1 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.4 // indirect - github.com/leodido/go-urn v1.2.4 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect + github.com/leodido/go-urn v1.4.0 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -75,10 +96,16 @@ require ( github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // 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/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/spf13/afero v1.14.0 // indirect github.com/spf13/cast v1.9.2 // 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/tdewolff/parse/v2 v2.8.3 // indirect github.com/tidwall/gjson v1.14.1 // indirect github.com/tidwall/match v1.1.1 // indirect @@ -86,20 +113,29 @@ require ( 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.uber.org/mock v0.6.0 // indirect go.uber.org/multierr v1.10.0 // indirect - golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.46.0 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/arch v0.24.0 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/mod v0.33.0 // indirect golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.39.0 // indirect - google.golang.org/protobuf v1.36.8 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/tools v0.42.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect modernc.org/libc v1.22.5 // indirect modernc.org/mathutil v1.5.0 // indirect modernc.org/memory v1.5.0 // indirect modernc.org/sqlite v1.23.1 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect ) tool github.com/air-verse/air diff --git a/go.sum b/go.sum index f835c39..13cbea4 100644 --- a/go.sum +++ b/go.sum @@ -7,6 +7,12 @@ github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69 h1:+tu3HOoMXB7RX github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69/go.mod h1:L1AbZdiDllfyYH5l5OkAaZtk7VkWe89bPJFmnDBNHxg= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= +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/air-verse/air v1.64.5 h1:+gs/NgTzYYe+gGPyfHy3XxpJReQWC1pIsiKIg0LgNt4= github.com/air-verse/air v1.64.5/go.mod h1:OaJZSfZqf7wyjS2oP/CcEVyIt0JmZuPh5x1gdtklmmY= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= @@ -54,20 +60,34 @@ github.com/bep/tmc v0.5.1 h1:CsQnSC6MsomH64gw0cT5f+EwQDcvZz4AazKunFwTpuI= github.com/bep/tmc v0.5.1/go.mod h1:tGYHN8fS85aJPhDLgXETVKp+PR382OvFi2+q2GkGsq0= github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d h1:pVrfxiGfwelyab6n21ZBkbkmbevaf+WvMIiR7sr97hw= github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= +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/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 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/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME= github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= +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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= @@ -98,14 +118,20 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= 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/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 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.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= +github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls= github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo= github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k= github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw= @@ -115,8 +141,30 @@ 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.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +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.3 h1:qRSmj6Smz2rEBxMnLRBMeBWxbbOvuOoElvSvObIgwQc= +github.com/go-openapi/spec v0.22.3/go.mod h1:iIImLODL2loCh3Vnox8TY2YWYJZjMAKYyLH2Mu8lOZs= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +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.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +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.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= 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= @@ -125,6 +173,8 @@ 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-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= @@ -136,6 +186,10 @@ github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= 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/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw= github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0= github.com/gohugoio/go-i18n/v2 v2.1.3-0.20230805085216-e63c13218d0e h1:QArsSubW7eDh8APMXkByjQWvuljwPGAGQpJEFn0F0wY= @@ -221,6 +275,9 @@ github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +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/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -232,10 +289,14 @@ github.com/kyokomi/emoji/v2 v2.2.13 h1:GhTfQa67venUUvmleTNFnb+bi7S3aocF7ZCXU9fSO github.com/kyokomi/emoji/v2 v2.2.13/go.mod h1:JUcn42DTdsXJo1SWanHh4HKDEyPaR5CqkmoirZZP9qE= 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/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/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +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/makeworld-the-better-one/dither/v2 v2.4.0 h1:Az/dYXiTcwcRSe59Hzw4RI1rSnAZns+1msaCXetrMFE= github.com/makeworld-the-better-one/dither/v2 v2.4.0/go.mod h1:VBtN8DXO7SNtyGmLiGA7IsFeKrBkQPze1/iAeM95arc= github.com/marekm4/color-extractor v1.2.1 h1:3Zb2tQsn6bITZ8MBVhc33Qn1k5/SEuZ18mrXGUqIwn0= @@ -303,6 +364,10 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/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/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= @@ -314,12 +379,15 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= 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/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/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/silenceper/wechat/v2 v2.1.12 h1:hoBeuL7Mgafz/ox6rn6r02rffFxHZhu7E0SlDRa+m28= github.com/silenceper/wechat/v2 v2.1.12/go.mod h1:7Iu3EhQYVtDUJAj+ZVRy8yom75ga7aDWv8RurLkVm0s= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= @@ -333,6 +401,7 @@ github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqe 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.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -341,8 +410,16 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +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/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +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/tdewolff/minify/v2 v2.24.2 h1:vnY3nTulEAbCAAlxTxPPDkzG24rsq31SOzp63yT+7mo= github.com/tdewolff/minify/v2 v2.24.2/go.mod h1:1JrCtoZXaDbqioQZfk3Jdmr0GPJKiU7c1Apmb+7tCeE= github.com/tdewolff/parse/v2 v2.8.3 h1:5VbvtJ83cfb289A1HzRA9sf02iT8YyUwN84ezjkdY1I= @@ -369,11 +446,18 @@ github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVK github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= 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/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +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/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= github.com/yuin/goldmark-emoji v1.0.6 h1:QWfF2FYaXwL74tfGOW5izeiZepUDroDJfWubQI9HTHs= @@ -386,20 +470,31 @@ 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/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= +go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= +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.24.0 h1:qlJ3M9upxvFfwRM51tTg3Yl+8CP9vCC1E7vlFpgv99Y= +golang.org/x/arch v0.24.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 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-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -415,20 +510,29 @@ golang.org/x/image v0.30.0/go.mod h1:SAEUTxCCMWSrJcCy/4HwavEsfZZJlYxeHLc6tTiAe/c golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= +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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +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.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +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-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/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.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -449,27 +553,41 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/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-20211216021012-1d35b9e2eb4e/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-20220715151400-c0bba94af5f8/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= 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/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.6/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.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-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -488,6 +606,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -529,6 +649,9 @@ modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds= modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/sqlite v1.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM= modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY= rsc.io/qr v0.2.0/go.mod h1:IF+uZjkb9fqyeF/4tlBoynqmQxUoPfWEKh921coOuXs= +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/internal/controllers/env_controller.go b/internal/controllers/env_controller.go index d41c29b..73b2291 100644 --- a/internal/controllers/env_controller.go +++ b/internal/controllers/env_controller.go @@ -17,6 +17,17 @@ func NewEnvController(envService *services.EnvService) *EnvController { return &EnvController{envService: envService} } +// CreateEnvVar 创建环境变量 +// @Summary 创建环境变量 +// @Description 创建新的环境变量 +// @Tags 环境变量 +// @Accept json +// @Produce json +// @Security ApiKeyAuth +// @Param body body object true "环境变量信息" +// @Success 200 {object} utils.Response{data=vo.EnvVO} +// @Failure 400 {object} utils.Response +// @Router /env [post] func (ec *EnvController) CreateEnvVar(c *gin.Context) { userID := c.GetString("userID") @@ -41,6 +52,18 @@ func (ec *EnvController) CreateEnvVar(c *gin.Context) { utils.Success(c, vo.ToEnvVO(envVar)) } +// GetEnvVars 获取环境变量列表 +// @Summary 获取环境变量列表 +// @Description 分页获取环境变量列表,支持按名称筛选 +// @Tags 环境变量 +// @Accept json +// @Produce json +// @Security ApiKeyAuth +// @Param name query string false "按名称模糊查询" +// @Param page query int false "页码" +// @Param page_size query int false "每页数量" +// @Success 200 {object} utils.Response{data=utils.PaginationData{list=[]vo.EnvVO}} +// @Router /env [get] func (ec *EnvController) GetEnvVars(c *gin.Context) { userID := c.GetString("userID") p := utils.ParsePagination(c) @@ -49,12 +72,32 @@ func (ec *EnvController) GetEnvVars(c *gin.Context) { utils.PaginatedResponse(c, vo.ToEnvVOListFromModels(envVars), total, p) } +// GetAllEnvVars 获取所有环境变量 +// @Summary 获取所有环境变量 +// @Description 获取当前用户的所有环境变量(不分页) +// @Tags 环境变量 +// @Accept json +// @Produce json +// @Security ApiKeyAuth +// @Success 200 {object} utils.Response{data=[]vo.EnvVO} +// @Router /env/all [get] func (ec *EnvController) GetAllEnvVars(c *gin.Context) { userID := c.GetString("userID") envVars := ec.envService.GetEnvVarsByUserID(userID) utils.Success(c, vo.ToEnvVOListFromModels(envVars)) } +// GetEnvVar 获取环境变量详情 +// @Summary 获取环境变量详情 +// @Description 根据 ID 获取环境变量详情 +// @Tags 环境变量 +// @Accept json +// @Produce json +// @Security ApiKeyAuth +// @Param id path string true "环境变量ID" +// @Success 200 {object} utils.Response{data=vo.EnvVO} +// @Failure 404 {object} utils.Response +// @Router /env/{id} [get] func (ec *EnvController) GetEnvVar(c *gin.Context) { id := c.Param("id") if id == "" { @@ -71,6 +114,18 @@ func (ec *EnvController) GetEnvVar(c *gin.Context) { utils.Success(c, vo.ToEnvVO(envVar)) } +// UpdateEnvVar 更新环境变量 +// @Summary 更新环境变量 +// @Description 根据 ID 更新环境变量信息 +// @Tags 环境变量 +// @Accept json +// @Produce json +// @Security ApiKeyAuth +// @Param id path string true "环境变量ID" +// @Param body body object true "更新信息" +// @Success 200 {object} utils.Response{data=vo.EnvVO} +// @Failure 404 {object} utils.Response +// @Router /env/{id} [put] func (ec *EnvController) UpdateEnvVar(c *gin.Context) { id := c.Param("id") if id == "" { @@ -110,6 +165,18 @@ func (ec *EnvController) UpdateEnvVar(c *gin.Context) { utils.Success(c, vo.ToEnvVO(envVar)) } +// DeleteEnvVar 删除环境变量 +// @Summary 删除环境变量 +// @Description 根据 ID 删除环境变量,支持强制删除 +// @Tags 环境变量 +// @Accept json +// @Produce json +// @Security ApiKeyAuth +// @Param id path string true "环境变量ID" +// @Param force query bool false "是否强制删除" +// @Success 200 {object} utils.Response +// @Failure 409 {object} utils.Response{data=[]vo.TaskVO} "引用冲突" +// @Router /env/{id} [delete] func (ec *EnvController) DeleteEnvVar(c *gin.Context) { id := c.Param("id") if id == "" { @@ -137,6 +204,16 @@ func (ec *EnvController) DeleteEnvVar(c *gin.Context) { utils.SuccessMsg(c, "删除成功") } +// GetAssociatedTasks 获取关联任务 +// @Summary 获取关联任务 +// @Description 获取引用了该环境变量的任务列表 +// @Tags 环境变量 +// @Accept json +// @Produce json +// @Security ApiKeyAuth +// @Param id path string true "环境变量ID" +// @Success 200 {object} utils.Response{data=[]vo.TaskVO} +// @Router /env/{id}/tasks [get] func (ec *EnvController) GetAssociatedTasks(c *gin.Context) { id := c.Param("id") if id == "" { diff --git a/internal/controllers/log_controller.go b/internal/controllers/log_controller.go index 9038f39..a7c88bb 100644 --- a/internal/controllers/log_controller.go +++ b/internal/controllers/log_controller.go @@ -16,6 +16,20 @@ func NewLogController() *LogController { return &LogController{} } +// GetLogs 获取任务日志列表 +// @Summary 获取任务日志列表 +// @Description 分页获取任务日志列表,支持按任务 ID、任务名称、状态筛选 +// @Tags 日志 +// @Accept json +// @Produce json +// @Security ApiKeyAuth +// @Param task_id query string false "任务 ID" +// @Param task_name query string false "任务名称" +// @Param status query string false "状态" +// @Param page query int false "页码" +// @Param page_size query int false "每页数量" +// @Success 200 {object} utils.Response{data=utils.PaginationData{list=[]vo.TaskLogVO}} +// @Router /logs [get] func (lc *LogController) GetLogs(c *gin.Context) { p := utils.ParsePagination(c) taskID := c.DefaultQuery("task_id", "") @@ -85,6 +99,17 @@ func (lc *LogController) GetLogs(c *gin.Context) { utils.PaginatedResponse(c, result, total, p) } +// GetLogDetail 获取日志详情 +// @Summary 获取日志详情 +// @Description 根据 ID 获取任务日志详细内容(包含输出) +// @Tags 日志 +// @Accept json +// @Produce json +// @Security ApiKeyAuth +// @Param id path string true "日志ID" +// @Success 200 {object} utils.Response{data=vo.TaskLogVO} +// @Failure 404 {object} utils.Response +// @Router /logs/{id} [get] func (lc *LogController) GetLogDetail(c *gin.Context) { id := c.Param("id") if id == "" { @@ -101,6 +126,17 @@ func (lc *LogController) GetLogDetail(c *gin.Context) { utils.Success(c, vo.ToTaskLogVO(&log)) } +// ClearLogs 清空日志 +// @Summary 清空日志 +// @Description 清空所有日志或指定任务的日志 +// @Tags 日志 +// @Accept json +// @Produce json +// @Security ApiKeyAuth +// @Param body body object false "清空范围信息" +// @Success 200 {object} utils.Response +// @Failure 500 {object} utils.Response +// @Router /logs/clear [post] func (lc *LogController) ClearLogs(c *gin.Context) { var req struct { TaskID *string `json:"task_id"` @@ -126,6 +162,17 @@ func (lc *LogController) ClearLogs(c *gin.Context) { utils.SuccessMsg(c, "日志清空成功") } +// DeleteLog 删除日志 +// @Summary 删除日志 +// @Description 根据 ID 删除单条任务日志 +// @Tags 日志 +// @Accept json +// @Produce json +// @Security ApiKeyAuth +// @Param id path string true "日志ID" +// @Success 200 {object} utils.Response +// @Failure 500 {object} utils.Response +// @Router /logs/{id} [delete] func (lc *LogController) DeleteLog(c *gin.Context) { id := c.Param("id") if id == "" { diff --git a/internal/controllers/task_controller.go b/internal/controllers/task_controller.go index feacd79..f9b2c58 100644 --- a/internal/controllers/task_controller.go +++ b/internal/controllers/task_controller.go @@ -105,6 +105,21 @@ func (tc *TaskController) CreateTask(c *gin.Context) { utils.Success(c, vo.ToTaskVO(task)) } +// GetTasks 获取任务列表 +// @Summary 获取任务列表 +// @Description 分页获取任务列表,支持按名称、Agent ID、标签、类型筛选 +// @Tags 任务 +// @Accept json +// @Produce json +// @Security ApiKeyAuth +// @Param name query string false "任务名称" +// @Param agent_id query string false "Agent ID" +// @Param tags query string false "标签" +// @Param type query string false "任务类型" +// @Param page query int false "页码" +// @Param page_size query int false "每页数量" +// @Success 200 {object} utils.Response{data=utils.PaginationData{list=[]vo.TaskVO}} +// @Router /tasks [get] func (tc *TaskController) GetTasks(c *gin.Context) { p := utils.ParsePagination(c) name := c.DefaultQuery("name", "") @@ -122,6 +137,17 @@ func (tc *TaskController) GetTasks(c *gin.Context) { utils.PaginatedResponse(c, vo.ToTaskVOListFromModels(tasks), total, p) } +// GetTask 获取任务详情 +// @Summary 获取任务详情 +// @Description 根据 ID 获取任务详情 +// @Tags 任务 +// @Accept json +// @Produce json +// @Security ApiKeyAuth +// @Param id path string true "任务ID" +// @Success 200 {object} utils.Response{data=vo.TaskVO} +// @Failure 404 {object} utils.Response +// @Router /tasks/{id} [get] func (tc *TaskController) GetTask(c *gin.Context) { id := c.Param("id") if id == "" { @@ -138,6 +164,18 @@ func (tc *TaskController) GetTask(c *gin.Context) { utils.Success(c, vo.ToTaskVO(task)) } +// UpdateTask 更新任务 +// @Summary 更新任务 +// @Description 根据 ID 更新任务信息 +// @Tags 任务 +// @Accept json +// @Produce json +// @Security ApiKeyAuth +// @Param id path string true "任务ID" +// @Param body body object true "任务更新信息" +// @Success 200 {object} utils.Response{data=vo.TaskVO} +// @Failure 404 {object} utils.Response +// @Router /tasks/{id} [put] func (tc *TaskController) UpdateTask(c *gin.Context) { id := c.Param("id") if id == "" { @@ -221,6 +259,17 @@ func (tc *TaskController) UpdateTask(c *gin.Context) { utils.Success(c, vo.ToTaskVO(task)) } +// DeleteTask 删除任务 +// @Summary 删除任务 +// @Description 根据 ID 删除任务 +// @Tags 任务 +// @Accept json +// @Produce json +// @Security ApiKeyAuth +// @Param id path string true "任务ID" +// @Success 200 {object} utils.Response +// @Failure 404 {object} utils.Response +// @Router /tasks/{id} [delete] func (tc *TaskController) DeleteTask(c *gin.Context) { id := c.Param("id") if id == "" { @@ -251,6 +300,17 @@ func (tc *TaskController) DeleteTask(c *gin.Context) { utils.SuccessMsg(c, "删除成功") } +// StopTask 停止任务 +// @Summary 停止任务 +// @Description 根据运行日志 ID 停止正在执行的任务 +// @Tags 任务 +// @Accept json +// @Produce json +// @Security ApiKeyAuth +// @Param logID path string true "运行日志ID" +// @Success 200 {object} utils.Response +// @Failure 400 {object} utils.Response +// @Router /tasks/stop/{logID} [post] func (tc *TaskController) StopTask(c *gin.Context) { logID := c.Param("logID") if logID == "" { diff --git a/internal/middleware/auth.go b/internal/middleware/auth.go index e8f6670..5e2f985 100644 --- a/internal/middleware/auth.go +++ b/internal/middleware/auth.go @@ -2,6 +2,7 @@ package middleware import ( "encoding/json" + "net/http" "time" "github.com/engigu/baihu-panel/internal/constant" @@ -115,3 +116,25 @@ func SetAuthCookie(c *gin.Context, token string, expireDays int) { func ClearAuthCookie(c *gin.Context) { c.SetCookie(constant.CookieName, "", -1, "/", "", false, true) } + +// SwaggerAuth Swagger 认证中间件 (Basic Auth) +func SwaggerAuth() gin.HandlerFunc { + return func(c *gin.Context) { + cfg := services.GetConfig() + if !cfg.Swagger.Enabled { + c.Status(404) + c.Abort() + return + } + + user, password, hasAuth := c.Request.BasicAuth() + if hasAuth && user == cfg.Swagger.User && password == cfg.Swagger.Password { + c.Next() + return + } + + c.Header("WWW-Authenticate", `Basic realm="restricted"`) + c.Status(http.StatusUnauthorized) + c.Abort() + } +} diff --git a/internal/router/router.go b/internal/router/router.go index b39cb41..a946e28 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -11,6 +11,8 @@ import ( "github.com/engigu/baihu-panel/internal/static" "github.com/gin-gonic/gin" + swaggerFiles "github.com/swaggo/files" + ginSwagger "github.com/swaggo/gin-swagger" ) type Controllers struct { @@ -83,6 +85,9 @@ func Setup(c *Controllers) *gin.Engine { }) } + // Swagger documentation (带 Basic Auth 认证) + root.GET("/swagger/*any", middleware.SwaggerAuth(), ginSwagger.WrapHandler(swaggerFiles.Handler)) + // API 路由组 api := root.Group("/api/v1") { diff --git a/internal/services/config_service.go b/internal/services/config_service.go index 3ff70f8..f94f321 100644 --- a/internal/services/config_service.go +++ b/internal/services/config_service.go @@ -31,10 +31,17 @@ type SecurityConfig struct { Secret string `ini:"secret"` } +type SwaggerConfig struct { + Enabled bool `ini:"enabled"` + User string `ini:"user"` + Password string `ini:"password"` +} + type AppConfig struct { Server ServerConfig `ini:"server"` Database DatabaseConfig `ini:"database"` Security SecurityConfig `ini:"security"` + Swagger SwaggerConfig `ini:"swagger"` } var Config *AppConfig @@ -75,6 +82,11 @@ func LoadConfig(path string) (*AppConfig, error) { Security: SecurityConfig{ Secret: "", }, + Swagger: SwaggerConfig{ + Enabled: false, + User: "admin", + Password: "swagger_password", + }, } // 检查配置文件是否存在 @@ -141,6 +153,16 @@ func applyEnvOverrides() { // Security getEnvStr("BH_SECRET", &Config.Security.Secret) + + // Swagger + vSwaggerEnabled := os.Getenv("BH_SWAGGER_ENABLED") + if vSwaggerEnabled == "true" || vSwaggerEnabled == "1" { + Config.Swagger.Enabled = true + } else if vSwaggerEnabled == "false" || vSwaggerEnabled == "0" { + Config.Swagger.Enabled = false + } + getEnvStr("BH_SWAGGER_USER", &Config.Swagger.User) + getEnvStr("BH_SWAGGER_PASSWORD", &Config.Swagger.Password) } func GetConfig() *AppConfig { diff --git a/internal/utils/pagination.go b/internal/utils/pagination.go index b147d1a..ce24e84 100644 --- a/internal/utils/pagination.go +++ b/internal/utils/pagination.go @@ -51,12 +51,20 @@ func (p Pagination) Offset() int { return (p.Page - 1) * p.PageSize } +// PaginationData 分页数据 +type PaginationData struct { + List interface{} `json:"list"` + Total int64 `json:"total"` + Page int `json:"page"` + PageSize int `json:"page_size"` +} + // PaginatedResponse 分页响应 func PaginatedResponse(c *gin.Context, data interface{}, total int64, p Pagination) { - Success(c, gin.H{ - "data": data, - "total": total, - "page": p.Page, - "page_size": p.PageSize, + Success(c, PaginationData{ + List: data, + Total: total, + Page: p.Page, + PageSize: p.PageSize, }) } diff --git a/main.go b/main.go index 6c5c1a3..de90b4a 100644 --- a/main.go +++ b/main.go @@ -7,8 +7,29 @@ import ( "github.com/engigu/baihu-panel/cmd" "github.com/engigu/baihu-panel/internal/bootstrap" "github.com/engigu/baihu-panel/internal/constant" + _ "github.com/engigu/baihu-panel/docs" // This will be generated by swag init ) +// @title Baihu Panel API +// @version 1.0 +// @description Baihu Panel API Server documentation. +// @termsOfService http://swagger.io/terms/ + +// @contact.name API Support +// @contact.url http://www.swagger.io/support +// @contact.email support@swagger.io + +// @license.name Apache 2.0 +// @license.url http://www.apache.org/licenses/LICENSE-2.0.html + +// @host localhost:8052 +// @BasePath /api/v1 +// @query.collection.format multi + +// @securityDefinitions.apikey ApiKeyAuth +// @in header +// @name Authorization + func printHelp() { fmt.Println("Usage: baihu [arguments]") fmt.Println("Available commands:")