From 953af7d8db8e97fdb020eba18ba55fbcf12cb230 Mon Sep 17 00:00:00 2001 From: ryan Date: Mon, 15 Jun 2026 16:38:44 +0800 Subject: [PATCH] refactor(util): move response helper to common/response and session logic to oauth - Relocated generic HTTP response helpers (Response, OK, Err, etc.) from internal/util/ to a dedicated internal/common/response/ package. - Renamed ResponseAny to Any to resolve revive stuttering warnings. - Moved session building options and cookie headers logic from internal/util/ to internal/apps/oauth/. - Removed all direct imports of Gin/Sessions/HTTP frameworks from internal/util/ to keep general utilities 100% pure. - Regenerated Swagger API documentation via make swagger. - All tests and make code-check compile and pass with 0 issues. --- docs/docs.go | 654 +++++++++--------- docs/swagger.json | 654 +++++++++--------- docs/swagger.yaml | 636 ++++++++--------- internal/apps/admin/auth_source/routers.go | 83 ++- .../apps/admin/auth_source/routers_test.go | 8 +- internal/apps/admin/cache/routers.go | 49 +- internal/apps/admin/db_manage/routers.go | 69 +- internal/apps/admin/logs/routers.go | 51 +- internal/apps/admin/push/channels.go | 71 +- internal/apps/admin/push/push_test.go | 16 +- internal/apps/admin/push/routers.go | 95 ++- internal/apps/admin/status/routers.go | 35 +- internal/apps/admin/system_config/routers.go | 87 ++- .../apps/admin/system_config/routers_test.go | 14 +- internal/apps/admin/task/routers.go | 161 +++-- internal/apps/admin/task/routers_test.go | 32 +- internal/apps/admin/template/routers.go | 103 ++- internal/apps/admin/template/routers_test.go | 8 +- internal/apps/admin/updater/routers.go | 33 +- internal/apps/admin/user/routers.go | 124 ++-- internal/apps/admin/user/routers_test.go | 22 +- internal/apps/cap/middleware.go | 11 +- internal/apps/cap/routers.go | 8 +- internal/apps/cap/routers_test.go | 9 +- internal/apps/config/routers.go | 17 +- internal/apps/config/routers_test.go | 9 +- internal/apps/custom/routers.go | 11 +- internal/apps/health/routers.go | 11 +- internal/apps/oauth/oauth_test.go | 2 +- internal/apps/oauth/routers.go | 28 +- internal/{util => apps/oauth}/session.go | 4 +- internal/apps/oauth/sources.go | 141 ++-- internal/apps/risk_control/middleware.go | 8 +- internal/apps/upload/file_management.go | 89 +-- internal/apps/upload/file_server.go | 11 +- internal/apps/upload/routers.go | 64 +- internal/apps/upload/stats.go | 25 +- internal/apps/user/access_tokens.go | 60 +- internal/apps/user/logics.go | 58 +- internal/apps/user/routers.go | 94 +-- internal/apps/user/routers_test.go | 11 +- .../{util => common/response}/response.go | 7 +- internal/router/router.go | 3 +- 43 files changed, 1833 insertions(+), 1853 deletions(-) rename internal/{util => apps/oauth}/session.go (94%) rename internal/{util => common/response}/response.go (81%) diff --git a/docs/docs.go b/docs/docs.go index 73bbe84d..bcd47595 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -55,7 +55,7 @@ const docTemplate = `{ "500": { "description": "内部服务错误", "schema": { - "$ref": "#/definitions/cap.RedeemResponse" + "$ref": "#/definitions/github_com_Rain-kl_Wavelet_internal_service_cap.RedeemResponse" } } } @@ -89,19 +89,19 @@ const docTemplate = `{ "200": { "description": "核销成功,返回 X-Cap-Token", "schema": { - "$ref": "#/definitions/cap.RedeemResponse" + "$ref": "#/definitions/github_com_Rain-kl_Wavelet_internal_service_cap.RedeemResponse" } }, "400": { "description": "参数错误或核销失败", "schema": { - "$ref": "#/definitions/cap.RedeemResponse" + "$ref": "#/definitions/github_com_Rain-kl_Wavelet_internal_service_cap.RedeemResponse" } }, "500": { "description": "内部服务错误", "schema": { - "$ref": "#/definitions/cap.RedeemResponse" + "$ref": "#/definitions/github_com_Rain-kl_Wavelet_internal_service_cap.RedeemResponse" } } } @@ -123,7 +123,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -160,7 +160,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -179,19 +179,19 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -230,7 +230,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -246,19 +246,19 @@ const docTemplate = `{ "400": { "description": "参数错误或验证失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -307,7 +307,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -323,25 +323,25 @@ const docTemplate = `{ "400": { "description": "参数错误或验证失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -376,7 +376,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -392,19 +392,19 @@ const docTemplate = `{ "400": { "description": "ID 无效或删除失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -453,7 +453,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -469,19 +469,19 @@ const docTemplate = `{ "400": { "description": "验证失败或认证源不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -506,25 +506,25 @@ const docTemplate = `{ "200": { "description": "清理成功", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "服务内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -563,31 +563,31 @@ const docTemplate = `{ "200": { "description": "更新成功", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "服务内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -614,13 +614,13 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", "properties": { "data": { - "$ref": "#/definitions/diskcache.Status" + "$ref": "#/definitions/github_com_Rain-kl_Wavelet_internal_diskcache.Status" } } } @@ -630,19 +630,19 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -673,19 +673,19 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "导出失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -712,7 +712,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -728,13 +728,13 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -761,7 +761,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -777,19 +777,19 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -830,7 +830,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -846,25 +846,25 @@ const docTemplate = `{ "400": { "description": "SQL 语句错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -891,7 +891,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -910,19 +910,19 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -965,7 +965,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -981,13 +981,13 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -1054,7 +1054,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1070,19 +1070,19 @@ const docTemplate = `{ "400": { "description": "ClickHouse 未启用或参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -1109,7 +1109,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1125,19 +1125,19 @@ const docTemplate = `{ "400": { "description": "ClickHouse 未启用", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -1174,7 +1174,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1226,7 +1226,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1263,7 +1263,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1315,7 +1315,7 @@ const docTemplate = `{ "200": { "description": "测试触发成功", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -1364,7 +1364,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1407,7 +1407,7 @@ const docTemplate = `{ "200": { "description": "删除成功", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -1434,7 +1434,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1486,7 +1486,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1523,7 +1523,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1584,7 +1584,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1628,7 +1628,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1674,7 +1674,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1737,7 +1737,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1788,7 +1788,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1825,7 +1825,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1841,13 +1841,13 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -1882,7 +1882,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1901,19 +1901,19 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -1952,7 +1952,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1968,25 +1968,25 @@ const docTemplate = `{ "400": { "description": "参数错误或配置键已存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2027,7 +2027,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2043,7 +2043,7 @@ const docTemplate = `{ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2079,7 +2079,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2095,25 +2095,25 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "配置不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2159,7 +2159,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2175,31 +2175,31 @@ const docTemplate = `{ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "配置不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2240,7 +2240,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2256,25 +2256,25 @@ const docTemplate = `{ "400": { "description": "任务类型不存在或参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "任务入队失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2329,7 +2329,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2345,13 +2345,13 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2387,7 +2387,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2403,25 +2403,25 @@ const docTemplate = `{ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "记录不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2457,7 +2457,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2473,31 +2473,31 @@ const docTemplate = `{ "400": { "description": "任务不支持重试或参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "记录不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "重试失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2524,7 +2524,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2543,13 +2543,13 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2588,7 +2588,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2604,25 +2604,25 @@ const docTemplate = `{ "400": { "description": "Cron 表达式无效、异步任务类型不存在或参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "保存定时任务失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2670,7 +2670,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2686,31 +2686,31 @@ const docTemplate = `{ "400": { "description": "Cron 表达式无效、参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "定时任务不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "修改定时任务失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2744,7 +2744,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2760,25 +2760,25 @@ const docTemplate = `{ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "删除定时任务失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2805,7 +2805,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2824,13 +2824,13 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2857,7 +2857,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2876,19 +2876,19 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2927,7 +2927,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2943,25 +2943,25 @@ const docTemplate = `{ "400": { "description": "参数错误或模板标识符已存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2997,7 +2997,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3013,25 +3013,25 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "模板不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3077,7 +3077,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3093,31 +3093,31 @@ const docTemplate = `{ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "模板不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3151,7 +3151,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3167,31 +3167,31 @@ const docTemplate = `{ "400": { "description": "不可删除系统模板", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "模板不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3218,7 +3218,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3234,19 +3234,19 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "查询失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3271,31 +3271,31 @@ const docTemplate = `{ "200": { "description": "升级已准备并即将重启", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "400": { "description": "当前版本不可升级", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "升级准备失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3361,7 +3361,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3377,13 +3377,13 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3428,13 +3428,13 @@ const docTemplate = `{ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "打包失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3480,19 +3480,19 @@ const docTemplate = `{ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "文件不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "服务内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3519,7 +3519,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3535,19 +3535,19 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3574,7 +3574,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3593,19 +3593,19 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3639,19 +3639,19 @@ const docTemplate = `{ "200": { "description": "删除成功", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无权操作", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "文件不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3703,7 +3703,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3719,25 +3719,25 @@ const docTemplate = `{ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3776,7 +3776,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3792,25 +3792,25 @@ const docTemplate = `{ "400": { "description": "参数错误或用户名已存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3846,7 +3846,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3862,31 +3862,31 @@ const docTemplate = `{ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "用户不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3920,7 +3920,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3936,31 +3936,31 @@ const docTemplate = `{ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限、尝试删除管理员或当前用户", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "用户不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4008,7 +4008,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4024,31 +4024,31 @@ const docTemplate = `{ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限或尝试禁用管理员", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "用户不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4071,7 +4071,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4093,7 +4093,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4139,7 +4139,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4155,19 +4155,19 @@ const docTemplate = `{ "400": { "description": "state 无效、参数错误或认证源错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "绑定场景未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "OAuth 认证失败或内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4194,7 +4194,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4213,13 +4213,13 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4256,7 +4256,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4272,13 +4272,13 @@ const docTemplate = `{ "400": { "description": "ID 无效或解除失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4308,7 +4308,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4324,13 +4324,13 @@ const docTemplate = `{ "400": { "description": "认证源不存在或未配置", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "Redis 异常 or 构造 URL 失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4357,7 +4357,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4373,7 +4373,7 @@ const docTemplate = `{ "500": { "description": "Session 清除失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4395,7 +4395,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4435,7 +4435,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4451,7 +4451,7 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4488,7 +4488,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4504,13 +4504,13 @@ const docTemplate = `{ "400": { "description": "认证源不存在或未启用", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "Redis 异常或构造 URL 失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4561,7 +4561,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4577,19 +4577,19 @@ const docTemplate = `{ "400": { "description": "请求参数错误或文件受限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4648,7 +4648,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4664,7 +4664,7 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4712,7 +4712,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4728,13 +4728,13 @@ const docTemplate = `{ "403": { "description": "无权操作", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "文件不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4766,19 +4766,19 @@ const docTemplate = `{ "200": { "description": "删除成功", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无权操作", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "文件不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4805,7 +4805,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4821,7 +4821,7 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4848,7 +4848,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4867,7 +4867,7 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4906,7 +4906,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4922,7 +4922,7 @@ const docTemplate = `{ "400": { "description": "参数错误或超限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4958,7 +4958,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4974,7 +4974,7 @@ const docTemplate = `{ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5010,7 +5010,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -5026,7 +5026,7 @@ const docTemplate = `{ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5062,7 +5062,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -5078,13 +5078,13 @@ const docTemplate = `{ "400": { "description": "原密码错误或新密码不符合要求", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "请先登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5120,7 +5120,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -5136,13 +5136,13 @@ const docTemplate = `{ "400": { "description": "用户名或密码错误、帐号已禁用等", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "服务内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5169,7 +5169,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -5185,7 +5185,7 @@ const docTemplate = `{ "500": { "description": "Session 清除失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5221,7 +5221,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -5237,13 +5237,13 @@ const docTemplate = `{ "400": { "description": "邮箱已被占用或参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5279,7 +5279,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -5295,13 +5295,13 @@ const docTemplate = `{ "400": { "description": "参数错误、用户名已存在或注册已关闭", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "服务内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5328,7 +5328,7 @@ const docTemplate = `{ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -5344,7 +5344,7 @@ const docTemplate = `{ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5378,13 +5378,13 @@ const docTemplate = `{ "200": { "description": "发送成功", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5425,25 +5425,25 @@ const docTemplate = `{ "400": { "description": "文件 ID 格式错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "文件未找到", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "服务内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5557,23 +5557,6 @@ const docTemplate = `{ } } }, - "cap.RedeemResponse": { - "type": "object", - "properties": { - "error": { - "type": "string" - }, - "expires": { - "type": "integer" - }, - "success": { - "type": "boolean" - }, - "token": { - "type": "string" - } - } - }, "cap.challengeRequest": { "type": "object", "properties": { @@ -5665,7 +5648,7 @@ const docTemplate = `{ } } }, - "diskcache.Status": { + "github_com_Rain-kl_Wavelet_internal_diskcache.Status": { "type": "object", "properties": { "base_path": { @@ -5688,6 +5671,23 @@ const docTemplate = `{ } } }, + "github_com_Rain-kl_Wavelet_internal_service_cap.RedeemResponse": { + "type": "object", + "properties": { + "error": { + "type": "string" + }, + "expires": { + "type": "integer" + }, + "success": { + "type": "boolean" + }, + "token": { + "type": "string" + } + } + }, "logger.LogEntry": { "type": "object", "properties": { @@ -6736,6 +6736,16 @@ const docTemplate = `{ } } }, + "response.Any": { + "type": "object", + "properties": { + "data": {}, + "error_msg": { + "type": "string", + "example": "" + } + } + }, "status.DatabaseInfoResponse": { "type": "object", "properties": { @@ -7534,16 +7544,6 @@ const docTemplate = `{ "type": "string" } } - }, - "util.ResponseAny": { - "type": "object", - "properties": { - "data": {}, - "error_msg": { - "type": "string", - "example": "" - } - } } }, "securityDefinitions": { diff --git a/docs/swagger.json b/docs/swagger.json index 5505a383..03f4a46d 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -48,7 +48,7 @@ "500": { "description": "内部服务错误", "schema": { - "$ref": "#/definitions/cap.RedeemResponse" + "$ref": "#/definitions/github_com_Rain-kl_Wavelet_internal_service_cap.RedeemResponse" } } } @@ -82,19 +82,19 @@ "200": { "description": "核销成功,返回 X-Cap-Token", "schema": { - "$ref": "#/definitions/cap.RedeemResponse" + "$ref": "#/definitions/github_com_Rain-kl_Wavelet_internal_service_cap.RedeemResponse" } }, "400": { "description": "参数错误或核销失败", "schema": { - "$ref": "#/definitions/cap.RedeemResponse" + "$ref": "#/definitions/github_com_Rain-kl_Wavelet_internal_service_cap.RedeemResponse" } }, "500": { "description": "内部服务错误", "schema": { - "$ref": "#/definitions/cap.RedeemResponse" + "$ref": "#/definitions/github_com_Rain-kl_Wavelet_internal_service_cap.RedeemResponse" } } } @@ -116,7 +116,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -153,7 +153,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -172,19 +172,19 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -223,7 +223,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -239,19 +239,19 @@ "400": { "description": "参数错误或验证失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -300,7 +300,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -316,25 +316,25 @@ "400": { "description": "参数错误或验证失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -369,7 +369,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -385,19 +385,19 @@ "400": { "description": "ID 无效或删除失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -446,7 +446,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -462,19 +462,19 @@ "400": { "description": "验证失败或认证源不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -499,25 +499,25 @@ "200": { "description": "清理成功", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "服务内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -556,31 +556,31 @@ "200": { "description": "更新成功", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "服务内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -607,13 +607,13 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", "properties": { "data": { - "$ref": "#/definitions/diskcache.Status" + "$ref": "#/definitions/github_com_Rain-kl_Wavelet_internal_diskcache.Status" } } } @@ -623,19 +623,19 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -666,19 +666,19 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "导出失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -705,7 +705,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -721,13 +721,13 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -754,7 +754,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -770,19 +770,19 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -823,7 +823,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -839,25 +839,25 @@ "400": { "description": "SQL 语句错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -884,7 +884,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -903,19 +903,19 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -958,7 +958,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -974,13 +974,13 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -1047,7 +1047,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1063,19 +1063,19 @@ "400": { "description": "ClickHouse 未启用或参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -1102,7 +1102,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1118,19 +1118,19 @@ "400": { "description": "ClickHouse 未启用", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -1167,7 +1167,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1219,7 +1219,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1256,7 +1256,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1308,7 +1308,7 @@ "200": { "description": "测试触发成功", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -1357,7 +1357,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1400,7 +1400,7 @@ "200": { "description": "删除成功", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -1427,7 +1427,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1479,7 +1479,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1516,7 +1516,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1577,7 +1577,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1621,7 +1621,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1667,7 +1667,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1730,7 +1730,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1781,7 +1781,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1818,7 +1818,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1834,13 +1834,13 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -1875,7 +1875,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1894,19 +1894,19 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -1945,7 +1945,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -1961,25 +1961,25 @@ "400": { "description": "参数错误或配置键已存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2020,7 +2020,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2036,7 +2036,7 @@ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2072,7 +2072,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2088,25 +2088,25 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "配置不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2152,7 +2152,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2168,31 +2168,31 @@ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "配置不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2233,7 +2233,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2249,25 +2249,25 @@ "400": { "description": "任务类型不存在或参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "任务入队失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2322,7 +2322,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2338,13 +2338,13 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2380,7 +2380,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2396,25 +2396,25 @@ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "记录不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2450,7 +2450,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2466,31 +2466,31 @@ "400": { "description": "任务不支持重试或参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "记录不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "重试失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2517,7 +2517,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2536,13 +2536,13 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2581,7 +2581,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2597,25 +2597,25 @@ "400": { "description": "Cron 表达式无效、异步任务类型不存在或参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "保存定时任务失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2663,7 +2663,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2679,31 +2679,31 @@ "400": { "description": "Cron 表达式无效、参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "定时任务不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "修改定时任务失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2737,7 +2737,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2753,25 +2753,25 @@ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "删除定时任务失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2798,7 +2798,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2817,13 +2817,13 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2850,7 +2850,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2869,19 +2869,19 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2920,7 +2920,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -2936,25 +2936,25 @@ "400": { "description": "参数错误或模板标识符已存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -2990,7 +2990,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3006,25 +3006,25 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "模板不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3070,7 +3070,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3086,31 +3086,31 @@ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "模板不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3144,7 +3144,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3160,31 +3160,31 @@ "400": { "description": "不可删除系统模板", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "模板不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3211,7 +3211,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3227,19 +3227,19 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "查询失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3264,31 +3264,31 @@ "200": { "description": "升级已准备并即将重启", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "400": { "description": "当前版本不可升级", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "升级准备失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3354,7 +3354,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3370,13 +3370,13 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3421,13 +3421,13 @@ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "打包失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3473,19 +3473,19 @@ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "文件不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "服务内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3512,7 +3512,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3528,19 +3528,19 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3567,7 +3567,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3586,19 +3586,19 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3632,19 +3632,19 @@ "200": { "description": "删除成功", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无权操作", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "文件不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3696,7 +3696,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3712,25 +3712,25 @@ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3769,7 +3769,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3785,25 +3785,25 @@ "400": { "description": "参数错误或用户名已存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3839,7 +3839,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3855,31 +3855,31 @@ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "用户不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -3913,7 +3913,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -3929,31 +3929,31 @@ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限、尝试删除管理员或当前用户", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "用户不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4001,7 +4001,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4017,31 +4017,31 @@ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无管理员权限或尝试禁用管理员", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "用户不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4064,7 +4064,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4086,7 +4086,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4132,7 +4132,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4148,19 +4148,19 @@ "400": { "description": "state 无效、参数错误或认证源错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "绑定场景未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "OAuth 认证失败或内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4187,7 +4187,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4206,13 +4206,13 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4249,7 +4249,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4265,13 +4265,13 @@ "400": { "description": "ID 无效或解除失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4301,7 +4301,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4317,13 +4317,13 @@ "400": { "description": "认证源不存在或未配置", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "Redis 异常 or 构造 URL 失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4350,7 +4350,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4366,7 +4366,7 @@ "500": { "description": "Session 清除失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4388,7 +4388,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4428,7 +4428,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4444,7 +4444,7 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4481,7 +4481,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4497,13 +4497,13 @@ "400": { "description": "认证源不存在或未启用", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "Redis 异常或构造 URL 失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4554,7 +4554,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4570,19 +4570,19 @@ "400": { "description": "请求参数错误或文件受限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4641,7 +4641,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4657,7 +4657,7 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4705,7 +4705,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4721,13 +4721,13 @@ "403": { "description": "无权操作", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "文件不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4759,19 +4759,19 @@ "200": { "description": "删除成功", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "403": { "description": "无权操作", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "文件不存在", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4798,7 +4798,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4814,7 +4814,7 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4841,7 +4841,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4860,7 +4860,7 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4899,7 +4899,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4915,7 +4915,7 @@ "400": { "description": "参数错误或超限", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -4951,7 +4951,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -4967,7 +4967,7 @@ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5003,7 +5003,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -5019,7 +5019,7 @@ "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5055,7 +5055,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -5071,13 +5071,13 @@ "400": { "description": "原密码错误或新密码不符合要求", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "请先登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5113,7 +5113,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -5129,13 +5129,13 @@ "400": { "description": "用户名或密码错误、帐号已禁用等", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "服务内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5162,7 +5162,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -5178,7 +5178,7 @@ "500": { "description": "Session 清除失败", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5214,7 +5214,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -5230,13 +5230,13 @@ "400": { "description": "邮箱已被占用或参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5272,7 +5272,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -5288,13 +5288,13 @@ "400": { "description": "参数错误、用户名已存在或注册已关闭", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "服务内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5321,7 +5321,7 @@ "schema": { "allOf": [ { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" }, { "type": "object", @@ -5337,7 +5337,7 @@ "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5371,13 +5371,13 @@ "200": { "description": "发送成功", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "400": { "description": "参数错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5418,25 +5418,25 @@ "400": { "description": "文件 ID 格式错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "401": { "description": "未登录", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "404": { "description": "文件未找到", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } }, "500": { "description": "服务内部错误", "schema": { - "$ref": "#/definitions/util.ResponseAny" + "$ref": "#/definitions/response.Any" } } } @@ -5550,23 +5550,6 @@ } } }, - "cap.RedeemResponse": { - "type": "object", - "properties": { - "error": { - "type": "string" - }, - "expires": { - "type": "integer" - }, - "success": { - "type": "boolean" - }, - "token": { - "type": "string" - } - } - }, "cap.challengeRequest": { "type": "object", "properties": { @@ -5658,7 +5641,7 @@ } } }, - "diskcache.Status": { + "github_com_Rain-kl_Wavelet_internal_diskcache.Status": { "type": "object", "properties": { "base_path": { @@ -5681,6 +5664,23 @@ } } }, + "github_com_Rain-kl_Wavelet_internal_service_cap.RedeemResponse": { + "type": "object", + "properties": { + "error": { + "type": "string" + }, + "expires": { + "type": "integer" + }, + "success": { + "type": "boolean" + }, + "token": { + "type": "string" + } + } + }, "logger.LogEntry": { "type": "object", "properties": { @@ -6729,6 +6729,16 @@ } } }, + "response.Any": { + "type": "object", + "properties": { + "data": {}, + "error_msg": { + "type": "string", + "example": "" + } + } + }, "status.DatabaseInfoResponse": { "type": "object", "properties": { @@ -7527,16 +7537,6 @@ "type": "string" } } - }, - "util.ResponseAny": { - "type": "object", - "properties": { - "data": {}, - "error_msg": { - "type": "string", - "example": "" - } - } } }, "securityDefinitions": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 13c3309d..97678072 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -57,17 +57,6 @@ definitions: token: type: string type: object - cap.RedeemResponse: - properties: - error: - type: string - expires: - type: integer - success: - type: boolean - token: - type: string - type: object cap.challengeRequest: properties: scope: @@ -128,7 +117,7 @@ definitions: description: '"select" 或 "exec"' type: string type: object - diskcache.Status: + github_com_Rain-kl_Wavelet_internal_diskcache.Status: properties: base_path: type: string @@ -143,6 +132,17 @@ definitions: ttl_minutes: type: integer type: object + github_com_Rain-kl_Wavelet_internal_service_cap.RedeemResponse: + properties: + error: + type: string + expires: + type: integer + success: + type: boolean + token: + type: string + type: object logger.LogEntry: properties: data: @@ -852,6 +852,13 @@ definitions: total: type: integer type: object + response.Any: + properties: + data: {} + error_msg: + example: "" + type: string + type: object status.DatabaseInfoResponse: properties: name: @@ -1392,13 +1399,6 @@ definitions: website: type: string type: object - util.ResponseAny: - properties: - data: {} - error_msg: - example: "" - type: string - type: object info: contact: name: Wavelet @@ -1431,7 +1431,7 @@ paths: "500": description: 内部服务错误 schema: - $ref: '#/definitions/cap.RedeemResponse' + $ref: '#/definitions/github_com_Rain-kl_Wavelet_internal_service_cap.RedeemResponse' summary: 生成人机验证难题 tags: - cap @@ -1453,15 +1453,15 @@ paths: "200": description: 核销成功,返回 X-Cap-Token schema: - $ref: '#/definitions/cap.RedeemResponse' + $ref: '#/definitions/github_com_Rain-kl_Wavelet_internal_service_cap.RedeemResponse' "400": description: 参数错误或核销失败 schema: - $ref: '#/definitions/cap.RedeemResponse' + $ref: '#/definitions/github_com_Rain-kl_Wavelet_internal_service_cap.RedeemResponse' "500": description: 内部服务错误 schema: - $ref: '#/definitions/cap.RedeemResponse' + $ref: '#/definitions/github_com_Rain-kl_Wavelet_internal_service_cap.RedeemResponse' summary: 校验人机验证解答 tags: - cap @@ -1475,7 +1475,7 @@ paths: description: 服务正常 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -1493,7 +1493,7 @@ paths: description: 认证源列表 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: items: @@ -1503,15 +1503,15 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取认证源列表 @@ -1535,7 +1535,7 @@ paths: description: 创建成功,返回认证源信息 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/model.AuthSource' @@ -1543,15 +1543,15 @@ paths: "400": description: 参数错误或验证失败 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 创建认证源 @@ -1574,7 +1574,7 @@ paths: description: 删除成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -1582,15 +1582,15 @@ paths: "400": description: ID 无效或删除失败 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 删除认证源 @@ -1620,7 +1620,7 @@ paths: description: 更新成功,返回更新后的认证源信息 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/model.AuthSource' @@ -1628,19 +1628,19 @@ paths: "400": description: 参数错误或验证失败 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 更新认证源 @@ -1671,7 +1671,7 @@ paths: description: 切换成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -1679,15 +1679,15 @@ paths: "400": description: 验证失败或认证源不存在 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 切换认证源启用状态 @@ -1702,19 +1702,19 @@ paths: "200": description: 清理成功 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 服务内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 清空缓存 @@ -1738,23 +1738,23 @@ paths: "200": description: 更新成功 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "400": description: 参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 服务内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 更新缓存配置 @@ -1770,23 +1770,23 @@ paths: description: 获取成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: - $ref: '#/definitions/diskcache.Status' + $ref: '#/definitions/github_com_Rain-kl_Wavelet_internal_diskcache.Status' type: object "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取缓存状态 @@ -1805,15 +1805,15 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 导出失败 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 导出数据库 @@ -1829,7 +1829,7 @@ paths: description: 获取成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/status.DatabaseInfoResponse' @@ -1837,11 +1837,11 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取数据库信息 @@ -1857,7 +1857,7 @@ paths: description: 获取成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/db_manage.DBOverviewResponse' @@ -1865,15 +1865,15 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取数据库运行概览 @@ -1898,7 +1898,7 @@ paths: description: 执行完毕 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/db_manage.ExecuteSQLResponse' @@ -1906,19 +1906,19 @@ paths: "400": description: SQL 语句错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 执行 SQL 查询 @@ -1934,7 +1934,7 @@ paths: description: 获取成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: items: @@ -1944,15 +1944,15 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取数据库所有表名 @@ -1979,7 +1979,7 @@ paths: description: 日志列表 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/logs.logsResponse' @@ -1987,11 +1987,11 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取系统日志 @@ -2034,7 +2034,7 @@ paths: description: 访问日志列表 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/logs.accessLogsResponse' @@ -2042,15 +2042,15 @@ paths: "400": description: ClickHouse 未启用或参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取用户访问日志 @@ -2066,7 +2066,7 @@ paths: description: 分析统计数据 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/logs.logsAnalyticsResponse' @@ -2074,15 +2074,15 @@ paths: "400": description: ClickHouse 未启用 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取访问日志分析数据 @@ -2105,7 +2105,7 @@ paths: description: 消息通道列表 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: items: @@ -2135,7 +2135,7 @@ paths: description: 创建成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/model.PushChannel' @@ -2161,7 +2161,7 @@ paths: "200": description: 删除成功 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 删除消息通道 @@ -2191,7 +2191,7 @@ paths: description: 更新成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/model.PushChannel' @@ -2211,7 +2211,7 @@ paths: description: 通道配置定义列表 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: items: @@ -2241,7 +2241,7 @@ paths: "200": description: 测试触发成功 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 测试通道连通性 @@ -2257,7 +2257,7 @@ paths: description: 通知事件列表 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: items: @@ -2287,7 +2287,7 @@ paths: description: 创建成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/model.PushEvent' @@ -2313,7 +2313,7 @@ paths: description: 删除成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -2346,7 +2346,7 @@ paths: description: 修改成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -2372,7 +2372,7 @@ paths: description: 切换成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -2392,7 +2392,7 @@ paths: description: 内置通知事件列表 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: items: @@ -2431,7 +2431,7 @@ paths: description: 推送历史列表 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/push.pushHistoriesResponse' @@ -2460,7 +2460,7 @@ paths: description: 测试成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -2480,7 +2480,7 @@ paths: description: 获取成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/status.SystemStatusResponse' @@ -2488,11 +2488,11 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取系统状态信息 @@ -2513,7 +2513,7 @@ paths: description: 系统配置列表 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: items: @@ -2523,15 +2523,15 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取系统配置列表 @@ -2555,7 +2555,7 @@ paths: description: 创建成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -2563,19 +2563,19 @@ paths: "400": description: 参数错误或配置键已存在 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 创建系统配置 @@ -2597,7 +2597,7 @@ paths: description: 系统配置详情 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/model.SystemConfig' @@ -2605,19 +2605,19 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "404": description: 配置不存在 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取单个系统配置 @@ -2646,7 +2646,7 @@ paths: description: 更新成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -2654,23 +2654,23 @@ paths: "400": description: 参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "404": description: 配置不存在 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 更新系统配置 @@ -2695,7 +2695,7 @@ paths: description: 测试执行完毕 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/system_config.TestSMTPResponse' @@ -2703,7 +2703,7 @@ paths: "400": description: 参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 测试 SMTP 邮件发送 @@ -2728,7 +2728,7 @@ paths: description: 任务已入队 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -2736,19 +2736,19 @@ paths: "400": description: 任务类型不存在或参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 任务入队失败 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 下发异步任务 @@ -2783,7 +2783,7 @@ paths: description: 任务执行记录列表 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: object @@ -2791,11 +2791,11 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 查询任务执行记录 @@ -2817,7 +2817,7 @@ paths: description: 任务执行详情 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/model.TaskExecution' @@ -2825,19 +2825,19 @@ paths: "400": description: 参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "404": description: 记录不存在 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 查询任务执行详情 @@ -2859,7 +2859,7 @@ paths: description: 新任务的 TaskID schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -2867,23 +2867,23 @@ paths: "400": description: 任务不支持重试或参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "404": description: 记录不存在 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 重试失败 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 重试失败任务 @@ -2899,7 +2899,7 @@ paths: description: 定时任务列表 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: items: @@ -2909,11 +2909,11 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取定时任务列表 @@ -2937,7 +2937,7 @@ paths: description: 创建成功的定时任务信息 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/model.Schedule' @@ -2945,19 +2945,19 @@ paths: "400": description: Cron 表达式无效、异步任务类型不存在或参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 保存定时任务失败 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 创建定时任务 @@ -2979,7 +2979,7 @@ paths: description: 删除结果 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -2987,19 +2987,19 @@ paths: "400": description: 参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 删除定时任务失败 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 删除定时任务 @@ -3028,7 +3028,7 @@ paths: description: 修改后的定时任务信息 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/model.Schedule' @@ -3036,23 +3036,23 @@ paths: "400": description: Cron 表达式无效、参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "404": description: 定时任务不存在 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 修改定时任务失败 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 修改定时任务 @@ -3068,7 +3068,7 @@ paths: description: 任务类型列表 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: items: @@ -3078,11 +3078,11 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取支持的任务类型 @@ -3098,7 +3098,7 @@ paths: description: 模板列表 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: items: @@ -3108,15 +3108,15 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取模板列表 @@ -3140,7 +3140,7 @@ paths: description: 创建成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -3148,19 +3148,19 @@ paths: "400": description: 参数错误或模板标识符已存在 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 创建模板 @@ -3182,7 +3182,7 @@ paths: description: 删除成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -3190,23 +3190,23 @@ paths: "400": description: 不可删除系统模板 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "404": description: 模板不存在 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 删除模板 @@ -3227,7 +3227,7 @@ paths: description: 模板详情 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/model.Template' @@ -3235,19 +3235,19 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "404": description: 模板不存在 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取单个模板 @@ -3276,7 +3276,7 @@ paths: description: 更新成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/model.Template' @@ -3284,23 +3284,23 @@ paths: "400": description: 参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "404": description: 模板不存在 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 更新模板 @@ -3316,7 +3316,7 @@ paths: description: 更新状态 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/updater.Status' @@ -3324,15 +3324,15 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 查询失败 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取应用更新状态 @@ -3347,23 +3347,23 @@ paths: "200": description: 升级已准备并即将重启 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "400": description: 当前版本不可升级 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 升级准备失败 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 下载并应用应用更新 @@ -3405,7 +3405,7 @@ paths: description: 查询成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/upload.listFilesResponse' @@ -3413,11 +3413,11 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取文件列表 @@ -3438,15 +3438,15 @@ paths: "200": description: 删除成功 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无权操作 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "404": description: 文件不存在 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 删除文件 @@ -3475,15 +3475,15 @@ paths: "400": description: 参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "404": description: 文件不存在 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 服务内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 下载单文件 @@ -3511,11 +3511,11 @@ paths: "400": description: 参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 打包失败 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 批量打包下载 @@ -3531,7 +3531,7 @@ paths: description: 获取成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/upload.fileStatsResponse' @@ -3539,15 +3539,15 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取文件统计数据 @@ -3563,7 +3563,7 @@ paths: description: 业务类型列表 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: items: @@ -3573,15 +3573,15 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取文件业务类型列表 @@ -3613,7 +3613,7 @@ paths: description: 用户列表 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/user.listUsersResponse' @@ -3621,19 +3621,19 @@ paths: "400": description: 参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取用户列表 @@ -3657,7 +3657,7 @@ paths: description: 创建成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/user.user' @@ -3665,19 +3665,19 @@ paths: "400": description: 参数错误或用户名已存在 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 创建用户 @@ -3699,7 +3699,7 @@ paths: description: 删除成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -3707,23 +3707,23 @@ paths: "400": description: 参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限、尝试删除管理员或当前用户 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "404": description: 用户不存在 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 删除用户 @@ -3744,7 +3744,7 @@ paths: description: 用户详情 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/user.user' @@ -3752,23 +3752,23 @@ paths: "400": description: 参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "404": description: 用户不存在 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取用户详情 @@ -3798,7 +3798,7 @@ paths: description: 更新成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -3806,23 +3806,23 @@ paths: "400": description: 参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无管理员权限或尝试禁用管理员 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "404": description: 用户不存在 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 更新用户状态 @@ -3839,7 +3839,7 @@ paths: "200": description: OK schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' summary: 获取公共配置 tags: - config @@ -3853,7 +3853,7 @@ paths: description: 成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -3881,7 +3881,7 @@ paths: description: 授权 URL schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/oauth.OAuthAuthorizeResponse' @@ -3889,11 +3889,11 @@ paths: "400": description: 认证源不存在或未启用 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: Redis 异常或构造 URL 失败 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' summary: 发起指定认证源授权 tags: - oauth @@ -3916,7 +3916,7 @@ paths: description: 登录或绑定成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/oauth.OAuthCallbackResult' @@ -3924,15 +3924,15 @@ paths: "400": description: state 无效、参数错误或认证源错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 绑定场景未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: OAuth 认证失败或内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' summary: OAuth 回调处理 tags: - oauth @@ -3946,7 +3946,7 @@ paths: description: 外部帐号列表 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: items: @@ -3956,11 +3956,11 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取外部帐号列表 @@ -3983,7 +3983,7 @@ paths: description: 解除绑定成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -3991,11 +3991,11 @@ paths: "400": description: ID 无效或解除失败 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 解除外部帐号绑定 @@ -4016,7 +4016,7 @@ paths: description: 授权 URL schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/oauth.OAuthAuthorizeResponse' @@ -4024,11 +4024,11 @@ paths: "400": description: 认证源不存在或未配置 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: Redis 异常 or 构造 URL 失败 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' summary: 获取登录授权地址 tags: - oauth @@ -4042,7 +4042,7 @@ paths: description: 退出成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -4050,7 +4050,7 @@ paths: "500": description: Session 清除失败 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 退出登录 @@ -4066,7 +4066,7 @@ paths: description: 登录源列表 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: items: @@ -4086,7 +4086,7 @@ paths: description: 用户信息 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/oauth.BasicUserInfo' @@ -4094,7 +4094,7 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取当前登录用户信息 @@ -4126,7 +4126,7 @@ paths: description: 上传成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/model.Upload' @@ -4134,15 +4134,15 @@ paths: "400": description: 请求参数错误或文件受限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 上传文件 @@ -4163,15 +4163,15 @@ paths: "200": description: 删除成功 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "403": description: 无权操作 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "404": description: 文件不存在 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 删除我的文件 @@ -4200,7 +4200,7 @@ paths: description: 更新成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/model.Upload' @@ -4208,11 +4208,11 @@ paths: "403": description: 无权操作 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "404": description: 文件不存在 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 更新我的文件信息 @@ -4249,7 +4249,7 @@ paths: description: 查询成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/upload.listMyFilesResponse' @@ -4257,7 +4257,7 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取我的文件列表 @@ -4273,7 +4273,7 @@ paths: description: 用户信息 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/oauth.BasicUserInfo' @@ -4281,7 +4281,7 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取当前登录用户信息 @@ -4297,7 +4297,7 @@ paths: description: 令牌列表 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: items: @@ -4307,7 +4307,7 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取当前用户的 AccessToken 列表 @@ -4331,7 +4331,7 @@ paths: description: 新建令牌成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/user.tokenResponse' @@ -4339,7 +4339,7 @@ paths: "400": description: 参数错误或超限 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 创建一个新的 AccessToken @@ -4361,7 +4361,7 @@ paths: description: 删除成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -4369,7 +4369,7 @@ paths: "400": description: 参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 删除一个 AccessToken @@ -4391,7 +4391,7 @@ paths: description: 令牌轮换成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/user.tokenResponse' @@ -4399,7 +4399,7 @@ paths: "400": description: 参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 轮换一个 AccessToken @@ -4424,7 +4424,7 @@ paths: description: 修改密码成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -4432,11 +4432,11 @@ paths: "400": description: 原密码错误或新密码不符合要求 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 请先登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' summary: 修改用户密码 tags: - user @@ -4459,7 +4459,7 @@ paths: description: 登录成功,返回用户信息 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/oauth.BasicUserInfo' @@ -4467,11 +4467,11 @@ paths: "400": description: 用户名或密码错误、帐号已禁用等 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 服务内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' summary: 用户密码登录 tags: - user @@ -4485,7 +4485,7 @@ paths: description: 退出成功 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: type: string @@ -4493,7 +4493,7 @@ paths: "500": description: Session 清除失败 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 用户退出登录 @@ -4518,7 +4518,7 @@ paths: description: 修改成功,返回更新后的用户信息 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/oauth.BasicUserInfo' @@ -4526,11 +4526,11 @@ paths: "400": description: 邮箱已被占用或参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' summary: 修改当前登录用户的个人资料 tags: - user @@ -4553,7 +4553,7 @@ paths: description: 注册并登录成功,返回用户信息 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/oauth.BasicUserInfo' @@ -4561,11 +4561,11 @@ paths: "400": description: 参数错误、用户名已存在或注册已关闭 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 服务内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' summary: 用户注册 tags: - user @@ -4579,7 +4579,7 @@ paths: description: 用户信息 schema: allOf: - - $ref: '#/definitions/util.ResponseAny' + - $ref: '#/definitions/response.Any' - properties: data: $ref: '#/definitions/oauth.BasicUserInfo' @@ -4587,7 +4587,7 @@ paths: "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' security: - SessionCookie: [] summary: 获取当前登录用户信息 @@ -4611,11 +4611,11 @@ paths: "200": description: 发送成功 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "400": description: 参数错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' summary: 发送邮箱验证码 tags: - user @@ -4642,19 +4642,19 @@ paths: "400": description: 文件 ID 格式错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "401": description: 未登录 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "404": description: 文件未找到 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' "500": description: 服务内部错误 schema: - $ref: '#/definitions/util.ResponseAny' + $ref: '#/definitions/response.Any' summary: 获取已上传文件 tags: - upload diff --git a/internal/apps/admin/auth_source/routers.go b/internal/apps/admin/auth_source/routers.go index cc65102e..2df74fdd 100644 --- a/internal/apps/admin/auth_source/routers.go +++ b/internal/apps/admin/auth_source/routers.go @@ -4,16 +4,15 @@ // Package auth_source 提供认证源管理功能 package auth_source -import ( - "errors" +import ("errors" "fmt" "net/http" "github.com/Rain-kl/Wavelet/internal/apps/admin" "github.com/Rain-kl/Wavelet/internal/model" - "github.com/Rain-kl/Wavelet/internal/util" "github.com/gin-gonic/gin" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") // AuthSourceRequest 创建或更新认证源的请求参数 type AuthSourceRequest struct { @@ -39,18 +38,18 @@ type ToggleAuthSourceRequest struct { // @Tags admin // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=[]model.AuthSource} "认证源列表" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=[]model.AuthSource} "认证源列表" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/auth-sources [get] func ListAuthSources(c *gin.Context) { sources, err := model.GetAuthSources(c.Request.Context()) if err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(sources)) + c.JSON(http.StatusOK, response.OK(sources)) } // CreateAuthSource 创建认证源 @@ -61,15 +60,15 @@ func ListAuthSources(c *gin.Context) { // @Produce json // @Security SessionCookie // @Param request body auth_source.AuthSourceRequest true "创建认证源参数" -// @Success 200 {object} util.ResponseAny{data=model.AuthSource} "创建成功,返回认证源信息" -// @Failure 400 {object} util.ResponseAny "参数错误或验证失败" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" +// @Success 200 {object} response.Any{data=model.AuthSource} "创建成功,返回认证源信息" +// @Failure 400 {object} response.Any "参数错误或验证失败" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" // @Router /api/v1/admin/auth-sources [post] func CreateAuthSource(c *gin.Context) { var req AuthSourceRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -85,11 +84,11 @@ func CreateAuthSource(c *gin.Context) { IconURL: req.IconURL, } if err := model.CreateAuthSource(c.Request.Context(), &source); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } source.Sanitize() - c.JSON(http.StatusOK, util.OK(source)) + c.JSON(http.StatusOK, response.OK(source)) } // UpdateAuthSource 更新认证源 @@ -101,22 +100,22 @@ func CreateAuthSource(c *gin.Context) { // @Security SessionCookie // @Param id path uint64 true "认证源 ID 或名称" // @Param request body auth_source.AuthSourceRequest true "更新认证源参数" -// @Success 200 {object} util.ResponseAny{data=model.AuthSource} "更新成功,返回更新后的认证源信息" -// @Failure 400 {object} util.ResponseAny "参数错误或验证失败" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=model.AuthSource} "更新成功,返回更新后的认证源信息" +// @Failure 400 {object} response.Any "参数错误或验证失败" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/auth-sources/{id} [put] func UpdateAuthSource(c *gin.Context) { id, err := parseSourceID(c) if err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } var req AuthSourceRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -134,16 +133,16 @@ func UpdateAuthSource(c *gin.Context) { } keepSecret := source.ClientSecret == "" if err := model.UpdateAuthSource(c.Request.Context(), &source, keepSecret); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } updated, err := model.GetAuthSourceByID(c.Request.Context(), id) if err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } updated.Sanitize() - c.JSON(http.StatusOK, util.OK(updated)) + c.JSON(http.StatusOK, response.OK(updated)) } // ToggleAuthSource 切换认证源启用状态 @@ -155,29 +154,29 @@ func UpdateAuthSource(c *gin.Context) { // @Security SessionCookie // @Param id path uint64 true "认证源 ID 或名称" // @Param request body auth_source.ToggleAuthSourceRequest true "启用状态" -// @Success 200 {object} util.ResponseAny{data=string} "切换成功" -// @Failure 400 {object} util.ResponseAny "验证失败或认证源不存在" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" +// @Success 200 {object} response.Any{data=string} "切换成功" +// @Failure 400 {object} response.Any "验证失败或认证源不存在" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" // @Router /api/v1/admin/auth-sources/{id}/toggle [put] func ToggleAuthSource(c *gin.Context) { id, err := parseSourceID(c) if err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } var req ToggleAuthSourceRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } if err := model.ToggleAuthSource(c.Request.Context(), id, req.IsActive); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } // DeleteAuthSource 删除认证源 @@ -187,22 +186,22 @@ func ToggleAuthSource(c *gin.Context) { // @Produce json // @Security SessionCookie // @Param id path uint64 true "认证源 ID 或名称" -// @Success 200 {object} util.ResponseAny{data=string} "删除成功" -// @Failure 400 {object} util.ResponseAny "ID 无效或删除失败" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" +// @Success 200 {object} response.Any{data=string} "删除成功" +// @Failure 400 {object} response.Any "ID 无效或删除失败" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" // @Router /api/v1/admin/auth-sources/{id} [delete] func DeleteAuthSource(c *gin.Context) { id, err := parseSourceID(c) if err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } if err := model.DeleteAuthSource(c.Request.Context(), id); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } func parseSourceID(c *gin.Context) (uint64, error) { diff --git a/internal/apps/admin/auth_source/routers_test.go b/internal/apps/admin/auth_source/routers_test.go index a108c195..8d9d3478 100644 --- a/internal/apps/admin/auth_source/routers_test.go +++ b/internal/apps/admin/auth_source/routers_test.go @@ -4,8 +4,7 @@ package auth_source -import ( - "bytes" +import ("bytes" "encoding/json" "net/http" "net/http/httptest" @@ -16,7 +15,8 @@ import ( "github.com/Rain-kl/Wavelet/internal/testhelper" "github.com/Rain-kl/Wavelet/internal/util" "github.com/gin-gonic/gin" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") func setupTestRouter(authUser *model.User) *gin.Engine { gin.SetMode(gin.TestMode) @@ -67,7 +67,7 @@ func TestListAuthSources(t *testing.T) { t.Errorf("expected 200 OK, got %d", w.Code) } - var resp util.ResponseAny + var resp response.Any _ = json.Unmarshal(w.Body.Bytes(), &resp) dataBytes, _ := json.Marshal(resp.Data) diff --git a/internal/apps/admin/cache/routers.go b/internal/apps/admin/cache/routers.go index c71b3167..3b313ddf 100644 --- a/internal/apps/admin/cache/routers.go +++ b/internal/apps/admin/cache/routers.go @@ -4,8 +4,7 @@ // Package cache provides HTTP handlers for managing disk cache. package cache -import ( - "context" +import ("context" "errors" "net/http" "strconv" @@ -13,10 +12,10 @@ import ( "github.com/Rain-kl/Wavelet/internal/db" "github.com/Rain-kl/Wavelet/internal/diskcache" "github.com/Rain-kl/Wavelet/internal/model" - "github.com/Rain-kl/Wavelet/internal/util" "github.com/gin-gonic/gin" "gorm.io/gorm" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") type updateCacheConfigRequest struct { MaxSizeMB int64 `json:"max_size_mb" binding:"required,min=1"` @@ -30,14 +29,14 @@ type updateCacheConfigRequest struct { // @Tags admin // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=diskcache.Status} "获取成功" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=diskcache.Status} "获取成功" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/cache/status [get] func GetCacheStatus(c *gin.Context) { status := diskcache.GetGlobalCache().Status() - c.JSON(http.StatusOK, util.OK(status)) + c.JSON(http.StatusOK, response.OK(status)) } // UpdateCacheConfig 更新磁盘缓存策略配置 @@ -48,16 +47,16 @@ func GetCacheStatus(c *gin.Context) { // @Produce json // @Param request body cache.updateCacheConfigRequest true "缓存配置请求体" // @Security SessionCookie -// @Success 200 {object} util.ResponseAny "更新成功" -// @Failure 400 {object} util.ResponseAny "参数错误" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "服务内部错误" +// @Success 200 {object} response.Any "更新成功" +// @Failure 400 {object} response.Any "参数错误" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "服务内部错误" // @Router /api/v1/admin/cache/config [post] func UpdateCacheConfig(c *gin.Context) { var req updateCacheConfigRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -65,26 +64,26 @@ func UpdateCacheConfig(c *gin.Context) { // Update Max Size if err := saveOrUpdateConfig(ctx, model.ConfigKeyDiskCacheMaxSizeMB, strconv.FormatInt(req.MaxSizeMB, 10)); err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } // Update Default TTL if err := saveOrUpdateConfig(ctx, model.ConfigKeyDiskCacheTTLMinutes, strconv.FormatInt(req.TTLMinutes, 10)); err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } // Update LRU Enabled if err := saveOrUpdateConfig(ctx, model.ConfigKeyDiskCacheLRUEnabled, strconv.FormatBool(req.LRUEnabled)); err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } // Trigger hot reloading in global cache diskcache.GetGlobalCache().ReloadConfig(ctx) - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } // ClearCache 一键清空所有磁盘缓存数据 @@ -93,17 +92,17 @@ func UpdateCacheConfig(c *gin.Context) { // @Tags admin // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny "清理成功" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "服务内部错误" +// @Success 200 {object} response.Any "清理成功" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "服务内部错误" // @Router /api/v1/admin/cache/clear [post] func ClearCache(c *gin.Context) { if err := diskcache.GetGlobalCache().Clear(); err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } func saveOrUpdateConfig(ctx context.Context, key string, value string) error { diff --git a/internal/apps/admin/db_manage/routers.go b/internal/apps/admin/db_manage/routers.go index 1399a2da..897fe9e3 100644 --- a/internal/apps/admin/db_manage/routers.go +++ b/internal/apps/admin/db_manage/routers.go @@ -6,8 +6,7 @@ // overview information, and executing custom SQL queries. package db_manage -import ( - "database/sql" +import ("database/sql" "fmt" "math" "net/http" @@ -17,10 +16,10 @@ import ( "github.com/Rain-kl/Wavelet/internal/config" "github.com/Rain-kl/Wavelet/internal/db" - "github.com/Rain-kl/Wavelet/internal/util" "github.com/gin-gonic/gin" "gorm.io/gorm" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") const ( binaryKB = 0 @@ -206,15 +205,15 @@ func getPostgresOverview(gormDB *gorm.DB) (DBOverviewResponse, error) { // @Tags admin // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=db_manage.DBOverviewResponse} "获取成功" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=db_manage.DBOverviewResponse} "获取成功" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/db-manage/overview [get] func GetDBOverview(c *gin.Context) { gormDB := db.DB(c.Request.Context()) if gormDB == nil { - c.JSON(http.StatusInternalServerError, util.Err("数据库未初始化")) + c.JSON(http.StatusInternalServerError, response.Err("数据库未初始化")) return } @@ -228,11 +227,11 @@ func GetDBOverview(c *gin.Context) { } if err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(overview)) + c.JSON(http.StatusOK, response.OK(overview)) } // ListDBTables 获取数据库所有表名 @@ -241,15 +240,15 @@ func GetDBOverview(c *gin.Context) { // @Tags admin // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=[]string} "获取成功" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=[]string} "获取成功" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/db-manage/tables [get] func ListDBTables(c *gin.Context) { gormDB := db.DB(c.Request.Context()) if gormDB == nil { - c.JSON(http.StatusInternalServerError, util.Err("数据库未初始化")) + c.JSON(http.StatusInternalServerError, response.Err("数据库未初始化")) return } @@ -263,24 +262,24 @@ func ListDBTables(c *gin.Context) { } if err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(tables)) + c.JSON(http.StatusOK, response.OK(tables)) } // GetDBTableData 获取数据表 data func GetDBTableData(c *gin.Context) { var req GetTableDataRequest if err := c.ShouldBindQuery(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } gormDB := db.DB(c.Request.Context()) if gormDB == nil { - c.JSON(http.StatusInternalServerError, util.Err("数据库未初始化")) + c.JSON(http.StatusInternalServerError, response.Err("数据库未初始化")) return } @@ -289,7 +288,7 @@ func GetDBTableData(c *gin.Context) { var total int64 if err := gormDB.Raw("SELECT count(*) FROM " + quotedTable).Scan(&total).Error; err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -304,7 +303,7 @@ func GetDBTableData(c *gin.Context) { rows, err := gormDB.Raw("SELECT * FROM "+quotedTable+" LIMIT ? OFFSET ?", limit, offset).Rows() if err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } defer func() { @@ -313,17 +312,17 @@ func GetDBTableData(c *gin.Context) { cols, err := rows.Columns() if err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } results, err := scanTableRows(rows, cols) if err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(TableDataResponse{ + c.JSON(http.StatusOK, response.OK(TableDataResponse{ Columns: cols, Total: total, Results: results, @@ -441,28 +440,28 @@ func executeSQLMutation(gormDB *gorm.DB, sqlStr string, startTime time.Time) (Ex // @Produce json // @Security SessionCookie // @Param request body db_manage.ExecuteSQLRequest true "SQL 请求参数" -// @Success 200 {object} util.ResponseAny{data=db_manage.ExecuteSQLResponse} "执行完毕" -// @Failure 400 {object} util.ResponseAny "SQL 语句错误" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=db_manage.ExecuteSQLResponse} "执行完毕" +// @Failure 400 {object} response.Any "SQL 语句错误" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/db-manage/query [post] func ExecuteSQL(c *gin.Context) { var req ExecuteSQLRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } gormDB := db.DB(c.Request.Context()) if gormDB == nil { - c.JSON(http.StatusInternalServerError, util.Err("数据库未初始化")) + c.JSON(http.StatusInternalServerError, response.Err("数据库未初始化")) return } trimmedSQL := strings.TrimSpace(req.SQL) if trimmedSQL == "" { - c.JSON(http.StatusBadRequest, util.Err("SQL 语句不能为空")) + c.JSON(http.StatusBadRequest, response.Err("SQL 语句不能为空")) return } @@ -489,9 +488,9 @@ func ExecuteSQL(c *gin.Context) { } if err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(resp)) + c.JSON(http.StatusOK, response.OK(resp)) } diff --git a/internal/apps/admin/logs/routers.go b/internal/apps/admin/logs/routers.go index c2d4acb7..5d6d2ca3 100644 --- a/internal/apps/admin/logs/routers.go +++ b/internal/apps/admin/logs/routers.go @@ -5,8 +5,7 @@ // Package logs 提供日志查询与分析功能 package logs -import ( - "context" +import ("context" "encoding/json" "fmt" "net/http" @@ -19,10 +18,10 @@ import ( "github.com/Rain-kl/Wavelet/internal/config" "github.com/Rain-kl/Wavelet/internal/db" "github.com/Rain-kl/Wavelet/internal/model" - "github.com/Rain-kl/Wavelet/internal/util" "github.com/Rain-kl/Wavelet/pkg/logger" "github.com/gin-gonic/gin" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") const ( defaultLimit = 200 @@ -48,9 +47,9 @@ type logsResponse struct { // @Security SessionCookie // @Param cursor query int false "日志游标,0=获取最新" default(0) // @Param limit query int false "每页条数" default(200) -// @Success 200 {object} util.ResponseAny{data=logs.logsResponse} "日志列表" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" +// @Success 200 {object} response.Any{data=logs.logsResponse} "日志列表" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" // @Router /api/v1/admin/logs [get] func GetLogs(c *gin.Context) { cursorStr := c.DefaultQuery("cursor", "0") @@ -58,7 +57,7 @@ func GetLogs(c *gin.Context) { var cursor, limit int if _, err := parsePositiveInt(cursorStr, &cursor); err != nil { - c.JSON(http.StatusBadRequest, util.Err(admin.InvalidCursorParam)) + c.JSON(http.StatusBadRequest, response.Err(admin.InvalidCursorParam)) return } if _, err := parsePositiveInt(limitStr, &limit); err != nil || limit <= 0 { @@ -78,7 +77,7 @@ func GetLogs(c *gin.Context) { resp.NextCursor = entries[0].Index } - c.JSON(http.StatusOK, util.OK(resp)) + c.JSON(http.StatusOK, response.OK(resp)) } // wsMessage WebSocket 消息格式 @@ -281,15 +280,15 @@ func fetchAccessLogDetails(ctx context.Context, whereClause string, args []inter // @Param path query string false "接口路径模糊搜索" // @Param start_time query string false "起始时间(RFC3339 或 YYYY-MM-DD HH:MM:SS)" // @Param end_time query string false "结束时间(RFC3339 或 YYYY-MM-DD HH:MM:SS)" -// @Success 200 {object} util.ResponseAny{data=logs.accessLogsResponse} "访问日志列表" -// @Failure 400 {object} util.ResponseAny "ClickHouse 未启用或参数错误" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" +// @Success 200 {object} response.Any{data=logs.accessLogsResponse} "访问日志列表" +// @Failure 400 {object} response.Any "ClickHouse 未启用或参数错误" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" // @Router /api/v1/admin/logs/access [get] func GetAccessLogs(c *gin.Context) { // 1. 检查 ClickHouse 是否启用 if !config.Config.ClickHouse.Enabled || db.ChConn == nil { - c.JSON(http.StatusBadRequest, util.Err("ClickHouse 存储服务未启用,无法检索访问日志")) + c.JSON(http.StatusBadRequest, response.Err("ClickHouse 存储服务未启用,无法检索访问日志")) return } @@ -310,11 +309,11 @@ func GetAccessLogs(c *gin.Context) { // 3. 构建过滤条件 conditions, args, userIDs, err := buildAccessLogFilters(c.Request.Context(), c) if err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } if userIDs != nil && len(userIDs) == 0 { - c.JSON(http.StatusOK, util.OK(accessLogsResponse{Total: 0, List: []accessLogItem{}})) + c.JSON(http.StatusOK, response.OK(accessLogsResponse{Total: 0, List: []accessLogItem{}})) return } @@ -327,22 +326,22 @@ func GetAccessLogs(c *gin.Context) { var total uint64 countQuery := fmt.Sprintf("SELECT count() FROM w_user_access_logs %s", whereClause) if err := db.ChConn.QueryRow(c.Request.Context(), countQuery, args...).Scan(&total); err != nil { - c.JSON(http.StatusInternalServerError, util.Err("查询 ClickHouse 日志统计失败: "+err.Error())) + c.JSON(http.StatusInternalServerError, response.Err("查询 ClickHouse 日志统计失败: "+err.Error())) return } if total == 0 { - c.JSON(http.StatusOK, util.OK(accessLogsResponse{Total: 0, List: []accessLogItem{}})) + c.JSON(http.StatusOK, response.OK(accessLogsResponse{Total: 0, List: []accessLogItem{}})) return } // 5. 分页查询明细数据 list, err := fetchAccessLogDetails(c.Request.Context(), whereClause, args, pageSize, offset) if err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(accessLogsResponse{ + c.JSON(http.StatusOK, response.OK(accessLogsResponse{ Total: total, List: list, })) @@ -381,15 +380,15 @@ type logsAnalyticsResponse struct { // @Tags admin // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=logs.logsAnalyticsResponse} "分析统计数据" -// @Failure 400 {object} util.ResponseAny "ClickHouse 未启用" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" +// @Success 200 {object} response.Any{data=logs.logsAnalyticsResponse} "分析统计数据" +// @Failure 400 {object} response.Any "ClickHouse 未启用" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" // @Router /api/v1/admin/logs/analytics [get] func GetLogsAnalytics(c *gin.Context) { // 1. 检查 ClickHouse 是否启用 if !config.Config.ClickHouse.Enabled || db.ChConn == nil { - c.JSON(http.StatusBadRequest, util.Err("ClickHouse 存储服务未启用,无法获取分析数据")) + c.JSON(http.StatusBadRequest, response.Err("ClickHouse 存储服务未启用,无法获取分析数据")) return } @@ -401,7 +400,7 @@ func GetLogsAnalytics(c *gin.Context) { browserList := queryBrowserDistribution(ctx, startTime) topUsers := queryTopActiveUsers(ctx, startTime) - c.JSON(http.StatusOK, util.OK(logsAnalyticsResponse{ + c.JSON(http.StatusOK, response.OK(logsAnalyticsResponse{ Trend: trendList, Browsers: browserList, TopUsers: topUsers, diff --git a/internal/apps/admin/push/channels.go b/internal/apps/admin/push/channels.go index 55e6e997..6c308068 100644 --- a/internal/apps/admin/push/channels.go +++ b/internal/apps/admin/push/channels.go @@ -3,8 +3,7 @@ package push -import ( - "encoding/json" +import ("encoding/json" "errors" "net/http" "strconv" @@ -12,11 +11,11 @@ import ( "github.com/Rain-kl/Wavelet/internal/db" "github.com/Rain-kl/Wavelet/internal/model" - "github.com/Rain-kl/Wavelet/internal/util" pkgpush "github.com/Rain-kl/Wavelet/pkg/push" "github.com/gin-gonic/gin" "gorm.io/gorm" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") // ListChannelDefinitions 获取各种消息通道的表单配置定义列表 // @Summary 获取所有消息通道配置字段定义 @@ -24,10 +23,10 @@ import ( // @Tags admin-push // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=[]Definition} "通道配置定义列表" +// @Success 200 {object} response.Any{data=[]Definition} "通道配置定义列表" // @Router /api/v1/admin/push/channels/definitions [get] func ListChannelDefinitions(c *gin.Context) { - c.JSON(http.StatusOK, util.OK(ListDefinitions())) + c.JSON(http.StatusOK, response.OK(ListDefinitions())) } // ListChannels 获取消息通道列表 @@ -36,16 +35,16 @@ func ListChannelDefinitions(c *gin.Context) { // @Tags admin-push // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=[]model.PushChannel} "消息通道列表" +// @Success 200 {object} response.Any{data=[]model.PushChannel} "消息通道列表" // @Router /api/v1/admin/push/channels [get] func ListChannels(c *gin.Context) { ctx := c.Request.Context() var channels []model.PushChannel if err := db.DB(ctx).Order("created_at DESC").Find(&channels).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(channels)) + c.JSON(http.StatusOK, response.OK(channels)) } // CreateChannelRequest 创建通道参数 @@ -67,12 +66,12 @@ type CreateChannelRequest struct { // @Produce json // @Security SessionCookie // @Param request body CreateChannelRequest true "创建参数" -// @Success 200 {object} util.ResponseAny{data=model.PushChannel} "创建成功" +// @Success 200 {object} response.Any{data=model.PushChannel} "创建成功" // @Router /api/v1/admin/push/channels [post] func CreateChannel(c *gin.Context) { var req CreateChannelRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -80,11 +79,11 @@ func CreateChannel(c *gin.Context) { var count int64 if err := db.DB(ctx).Model(&model.PushChannel{}).Where("name = ?", req.Name).Count(&count).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } if count > 0 { - c.JSON(http.StatusBadRequest, util.Err("channel name already exists")) + c.JSON(http.StatusBadRequest, response.Err("channel name already exists")) return } @@ -99,16 +98,16 @@ func CreateChannel(c *gin.Context) { } if err := channel.Validate(); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } if err := db.DB(ctx).Create(&channel).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(channel)) + c.JSON(http.StatusOK, response.OK(channel)) } // UpdateChannelRequest 修改通道参数 @@ -130,19 +129,19 @@ type UpdateChannelRequest struct { // @Security SessionCookie // @Param id path uint64 true "通道ID" // @Param request body UpdateChannelRequest true "更新参数" -// @Success 200 {object} util.ResponseAny{data=model.PushChannel} "更新成功" +// @Success 200 {object} response.Any{data=model.PushChannel} "更新成功" // @Router /api/v1/admin/push/channels/{id} [put] func UpdateChannel(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { - c.JSON(http.StatusBadRequest, util.Err("invalid channel id")) + c.JSON(http.StatusBadRequest, response.Err("invalid channel id")) return } var req UpdateChannelRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -151,10 +150,10 @@ func UpdateChannel(c *gin.Context) { var channel model.PushChannel if err := db.DB(ctx).Where("id = ?", id).First(&channel).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - c.JSON(http.StatusNotFound, util.Err("channel not found")) + c.JSON(http.StatusNotFound, response.Err("channel not found")) return } - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } @@ -166,16 +165,16 @@ func UpdateChannel(c *gin.Context) { channel.Enabled = req.Enabled if err := channel.Validate(); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } if err := db.DB(ctx).Save(&channel).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(channel)) + c.JSON(http.StatusOK, response.OK(channel)) } // DeleteChannel 删除消息通道 @@ -185,13 +184,13 @@ func UpdateChannel(c *gin.Context) { // @Produce json // @Security SessionCookie // @Param id path uint64 true "通道ID" -// @Success 200 {object} util.ResponseAny "删除成功" +// @Success 200 {object} response.Any "删除成功" // @Router /api/v1/admin/push/channels/{id} [delete] func DeleteChannel(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { - c.JSON(http.StatusBadRequest, util.Err("invalid channel id")) + c.JSON(http.StatusBadRequest, response.Err("invalid channel id")) return } @@ -199,19 +198,19 @@ func DeleteChannel(c *gin.Context) { var channel model.PushChannel if err := db.DB(ctx).Where("id = ?", id).First(&channel).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - c.JSON(http.StatusNotFound, util.Err("channel not found")) + c.JSON(http.StatusNotFound, response.Err("channel not found")) return } - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } if err := db.DB(ctx).Delete(&channel).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } // TestChannelRequest 测试通道连通性参数 @@ -232,12 +231,12 @@ type TestChannelRequest struct { // @Produce json // @Security SessionCookie // @Param request body TestChannelRequest true "测试参数" -// @Success 200 {object} util.ResponseAny "测试触发成功" +// @Success 200 {object} response.Any "测试触发成功" // @Router /api/v1/admin/push/channels/test [post] func TestChannel(c *gin.Context) { var req TestChannelRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -247,7 +246,7 @@ func TestChannel(c *gin.Context) { if req.Name != "" { var channel model.PushChannel if err := db.DB(ctx).Where("name = ?", req.Name).First(&channel).Error; err != nil { - c.JSON(http.StatusBadRequest, util.Err("channel not found")) + c.JSON(http.StatusBadRequest, response.Err("channel not found")) return } url = channel.URL @@ -276,7 +275,7 @@ func TestChannel(c *gin.Context) { } if err := tempChannel.Validate(); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } url = tempChannel.URL @@ -334,11 +333,11 @@ func TestChannel(c *gin.Context) { } if err := enqueuePushTask(ctx, payload); err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } // CustomPushRequest 外部公开推送请求参数 diff --git a/internal/apps/admin/push/push_test.go b/internal/apps/admin/push/push_test.go index 22c1ec20..fb77bce6 100644 --- a/internal/apps/admin/push/push_test.go +++ b/internal/apps/admin/push/push_test.go @@ -3,8 +3,7 @@ package push -import ( - "bytes" +import ("bytes" "context" "encoding/json" "net/http" @@ -25,7 +24,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gorm.io/gorm" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") var adminLoginEvent = EventMetadata{ Key: "admin_login", @@ -344,7 +344,7 @@ func TestPushRouters(t *testing.T) { r.ServeHTTP(w, req) assert.Equal(t, http.StatusOK, w.Code) - var resp util.ResponseAny + var resp response.Any err = json.Unmarshal(w.Body.Bytes(), &resp) require.NoError(t, err) @@ -415,7 +415,7 @@ func TestPushRouters(t *testing.T) { r.ServeHTTP(w, req) assert.Equal(t, http.StatusOK, w.Code) - var resp util.ResponseAny + var resp response.Any json.Unmarshal(w.Body.Bytes(), &resp) dataMap, ok := resp.Data.(map[string]any) @@ -449,7 +449,7 @@ func TestPushRouters(t *testing.T) { r.ServeHTTP(w, req) assert.Equal(t, http.StatusOK, w.Code) - var resp util.ResponseAny + var resp response.Any err := json.Unmarshal(w.Body.Bytes(), &resp) require.NoError(t, err) @@ -674,7 +674,7 @@ func TestPushChannelAPI(t *testing.T) { r.ServeHTTP(w, req) assert.Equal(t, http.StatusOK, w.Code) - var resp util.ResponseAny + var resp response.Any json.Unmarshal(w.Body.Bytes(), &resp) dataMap, ok := resp.Data.(map[string]any) @@ -689,7 +689,7 @@ func TestPushChannelAPI(t *testing.T) { r.ServeHTTP(w, req) assert.Equal(t, http.StatusOK, w.Code) - var resp util.ResponseAny + var resp response.Any json.Unmarshal(w.Body.Bytes(), &resp) list, ok := resp.Data.([]any) assert.True(t, ok) diff --git a/internal/apps/admin/push/routers.go b/internal/apps/admin/push/routers.go index f47064a6..9c8a9a68 100644 --- a/internal/apps/admin/push/routers.go +++ b/internal/apps/admin/push/routers.go @@ -4,8 +4,7 @@ // Package push defines push notification HTTP routes. package push -import ( - "context" +import ("context" "encoding/json" "errors" "fmt" @@ -16,11 +15,11 @@ import ( "github.com/Rain-kl/Wavelet/internal/db" "github.com/Rain-kl/Wavelet/internal/model" "github.com/Rain-kl/Wavelet/internal/task" - "github.com/Rain-kl/Wavelet/internal/util" "github.com/Rain-kl/Wavelet/pkg/push" "github.com/gin-gonic/gin" "gorm.io/gorm" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") // UpdateEventRequest 更新事件请求参数 type UpdateEventRequest struct { @@ -70,17 +69,17 @@ func SyncEvents(ctx context.Context) error { // @Tags admin-push // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=[]model.PushEvent} "通知事件列表" +// @Success 200 {object} response.Any{data=[]model.PushEvent} "通知事件列表" // @Router /api/v1/admin/push/events [get] func ListEvents(c *gin.Context) { ctx := c.Request.Context() var events []model.PushEvent if err := db.DB(ctx).Order("created_at DESC").Find(&events).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(events)) + c.JSON(http.StatusOK, response.OK(events)) } // CreateEventRequest 创建事件请求参数 @@ -108,10 +107,10 @@ func findBuiltInEvent(key string) (EventMetadata, bool) { // @Tags admin-push // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=[]EventMetadata} "内置通知事件列表" +// @Success 200 {object} response.Any{data=[]EventMetadata} "内置通知事件列表" // @Router /api/v1/admin/push/events/builtin [get] func ListBuiltInEvents(c *gin.Context) { - c.JSON(http.StatusOK, util.OK(BuiltInEvents)) + c.JSON(http.StatusOK, response.OK(BuiltInEvents)) } func getEventInfo(req CreateEventRequest) (string, string, []byte, error) { @@ -162,12 +161,12 @@ func getEventInfo(req CreateEventRequest) (string, string, []byte, error) { // @Produce json // @Security SessionCookie // @Param request body CreateEventRequest true "创建参数" -// @Success 200 {object} util.ResponseAny{data=model.PushEvent} "创建成功" +// @Success 200 {object} response.Any{data=model.PushEvent} "创建成功" // @Router /api/v1/admin/push/events [post] func CreateEvent(c *gin.Context) { var req CreateEventRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -175,18 +174,18 @@ func CreateEvent(c *gin.Context) { eventKey, eventName, defaultTemplateBytes, err := getEventInfo(req) if err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } // 2. 检查是否已经创建过该事件的配置 var count int64 if err := db.DB(ctx).Model(&model.PushEvent{}).Where("event_key = ?", eventKey).Count(&count).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } if count > 0 { - c.JSON(http.StatusBadRequest, util.Err("this notification event is already configured")) + c.JSON(http.StatusBadRequest, response.Err("this notification event is already configured")) return } @@ -197,7 +196,7 @@ func CreateEvent(c *gin.Context) { } else { var tempMap map[string]any if err := json.Unmarshal([]byte(templateStr), &tempMap); err != nil { - c.JSON(http.StatusBadRequest, util.Err("custom template is not a valid JSON format")) + c.JSON(http.StatusBadRequest, response.Err("custom template is not a valid JSON format")) return } } @@ -223,16 +222,16 @@ func CreateEvent(c *gin.Context) { } if err := event.Validate(); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } if err := db.DB(ctx).Create(&event).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(event)) + c.JSON(http.StatusOK, response.OK(event)) } // DeleteEvent 删除通知事件配置 @@ -242,13 +241,13 @@ func CreateEvent(c *gin.Context) { // @Produce json // @Security SessionCookie // @Param id path int true "事件 ID" -// @Success 200 {object} util.ResponseAny{data=string} "删除成功" +// @Success 200 {object} response.Any{data=string} "删除成功" // @Router /api/v1/admin/push/events/{id} [delete] func DeleteEvent(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { - c.JSON(http.StatusBadRequest, util.Err("invalid event id")) + c.JSON(http.StatusBadRequest, response.Err("invalid event id")) return } @@ -256,19 +255,19 @@ func DeleteEvent(c *gin.Context) { var event model.PushEvent if err := db.DB(ctx).First(&event, id).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - c.JSON(http.StatusNotFound, util.Err("notification event not found")) + c.JSON(http.StatusNotFound, response.Err("notification event not found")) } else { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) } return } if err := db.DB(ctx).Delete(&event).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } // UpdateEvent 更新通知事件 @@ -280,28 +279,28 @@ func DeleteEvent(c *gin.Context) { // @Security SessionCookie // @Param id path int true "事件 ID" // @Param request body push.UpdateEventRequest true "更新参数" -// @Success 200 {object} util.ResponseAny{data=string} "修改成功" +// @Success 200 {object} response.Any{data=string} "修改成功" // @Router /api/v1/admin/push/events/{id} [put] func UpdateEvent(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { - c.JSON(http.StatusBadRequest, util.Err("invalid event id")) + c.JSON(http.StatusBadRequest, response.Err("invalid event id")) return } var req UpdateEventRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } var event model.PushEvent if err := db.DB(c.Request.Context()).First(&event, id).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - c.JSON(http.StatusNotFound, util.Err("notification event not found")) + c.JSON(http.StatusNotFound, response.Err("notification event not found")) } else { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) } return } @@ -312,16 +311,16 @@ func UpdateEvent(c *gin.Context) { event.Enabled = req.Enabled if err := event.Validate(); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } if err := db.DB(c.Request.Context()).Save(&event).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } // ToggleEvent 快捷切换通知事件启用状态 @@ -331,33 +330,33 @@ func UpdateEvent(c *gin.Context) { // @Produce json // @Security SessionCookie // @Param id path int true "事件 ID" -// @Success 200 {object} util.ResponseAny{data=string} "切换成功" +// @Success 200 {object} response.Any{data=string} "切换成功" // @Router /api/v1/admin/push/events/{id}/toggle [post] func ToggleEvent(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { - c.JSON(http.StatusBadRequest, util.Err("invalid event id")) + c.JSON(http.StatusBadRequest, response.Err("invalid event id")) return } var event model.PushEvent if err := db.DB(c.Request.Context()).First(&event, id).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - c.JSON(http.StatusNotFound, util.Err("notification event not found")) + c.JSON(http.StatusNotFound, response.Err("notification event not found")) } else { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) } return } event.Enabled = !event.Enabled if err := db.DB(c.Request.Context()).Model(&event).Update("enabled", event.Enabled).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(event.Enabled)) + c.JSON(http.StatusOK, response.OK(event.Enabled)) } // pushHistoriesResponse 推送历史分页响应 @@ -378,7 +377,7 @@ type pushHistoriesResponse struct { // @Param page_size query int false "分页大小" // @Param event_key query string false "过滤事件名称" // @Param status query string false "过滤发送状态" -// @Success 200 {object} util.ResponseAny{data=pushHistoriesResponse} "推送历史列表" +// @Success 200 {object} response.Any{data=pushHistoriesResponse} "推送历史列表" // @Router /api/v1/admin/push/histories [get] func ListHistories(c *gin.Context) { pageStr := c.DefaultQuery("page", "1") @@ -405,18 +404,18 @@ func ListHistories(c *gin.Context) { var total int64 if err := query.Count(&total).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } var results []model.PushHistory offset := (page - 1) * pageSize if err := query.Offset(offset).Limit(pageSize).Find(&results).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(map[string]any{ + c.JSON(http.StatusOK, response.OK(map[string]any{ "total": total, "results": results, })) @@ -430,24 +429,24 @@ func ListHistories(c *gin.Context) { // @Produce json // @Security SessionCookie // @Param request body push.TestPushRequest true "测试请求体" -// @Success 200 {object} util.ResponseAny{data=string} "测试成功" +// @Success 200 {object} response.Any{data=string} "测试成功" // @Router /api/v1/admin/push/test [post] func TestPush(c *gin.Context) { var req TestPushRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } pusher, err := push.GetPusher(req.Config.Channel) if err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } // 校验配置 if err := pusher.ValidateConfig(req.Config); err != nil { - c.JSON(http.StatusBadRequest, util.Err(fmt.Sprintf("validation failed: %v", err))) + c.JSON(http.StatusBadRequest, response.Err(fmt.Sprintf("validation failed: %v", err))) return } @@ -479,9 +478,9 @@ func TestPush(c *gin.Context) { err = pusher.Send(c.Request.Context(), req.Config, req.Target, testBody, "", nil) if err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } diff --git a/internal/apps/admin/status/routers.go b/internal/apps/admin/status/routers.go index bf091c6c..2890ada8 100644 --- a/internal/apps/admin/status/routers.go +++ b/internal/apps/admin/status/routers.go @@ -5,8 +5,7 @@ // Package status 提供系统状态查询接口 package status -import ( - "context" +import ("context" "fmt" "log" "math" @@ -18,9 +17,9 @@ import ( "github.com/Rain-kl/Wavelet/internal/config" "github.com/Rain-kl/Wavelet/internal/db" - "github.com/Rain-kl/Wavelet/internal/util" "github.com/gin-gonic/gin" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") // startTime 记录服务启动时间 var startTime = time.Now() @@ -135,9 +134,9 @@ func formatDuration(d time.Duration) string { // @Tags admin // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=status.SystemStatusResponse} "获取成功" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" +// @Success 200 {object} response.Any{data=status.SystemStatusResponse} "获取成功" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" // @Router /api/v1/admin/status [get] func GetSystemStatus(c *gin.Context) { var m runtime.MemStats @@ -194,7 +193,7 @@ func GetSystemStatus(c *gin.Context) { NumGC: m.NumGC, } - c.JSON(http.StatusOK, util.OK(res)) + c.JSON(http.StatusOK, response.OK(res)) } // DatabaseInfoResponse 数据库信息响应结构体 @@ -249,9 +248,9 @@ func getPostgresInfo(ctx context.Context) DatabaseInfoResponse { // @Tags admin // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=status.DatabaseInfoResponse} "获取成功" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" +// @Success 200 {object} response.Any{data=status.DatabaseInfoResponse} "获取成功" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" // @Router /api/v1/admin/db-info [get] func GetDatabaseInfo(c *gin.Context) { var info DatabaseInfoResponse @@ -260,7 +259,7 @@ func GetDatabaseInfo(c *gin.Context) { } else { info = getPostgresInfo(c.Request.Context()) } - c.JSON(http.StatusOK, util.OK(info)) + c.JSON(http.StatusOK, response.OK(info)) } // ExportDatabase 导出数据库 @@ -270,9 +269,9 @@ func GetDatabaseInfo(c *gin.Context) { // @Produce application/octet-stream // @Security SessionCookie // @Success 200 {file} binary "数据库文件" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "导出失败" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "导出失败" // @Router /api/v1/admin/db-export [get] func ExportDatabase(c *gin.Context) { if !config.Config.Database.Enabled { @@ -291,7 +290,7 @@ func exportSQLite(c *gin.Context) { f, err := os.Open(path) //nolint:gosec // path is loaded from server startup configuration, not user input if err != nil { - c.JSON(http.StatusInternalServerError, util.Err("无法打开数据库文件: "+err.Error())) + c.JSON(http.StatusInternalServerError, response.Err("无法打开数据库文件: "+err.Error())) return } defer func() { @@ -302,7 +301,7 @@ func exportSQLite(c *gin.Context) { fi, err := f.Stat() if err != nil { - c.JSON(http.StatusInternalServerError, util.Err("无法读取数据库文件信息: "+err.Error())) + c.JSON(http.StatusInternalServerError, response.Err("无法读取数据库文件信息: "+err.Error())) return } @@ -320,7 +319,7 @@ func exportPostgres(c *gin.Context) { // 检查 pg_dump 是否可用 pgDumpPath, err := exec.LookPath("pg_dump") if err != nil { - c.JSON(http.StatusInternalServerError, util.Err("pg_dump 不可用,请确保服务器已安装 PostgreSQL 客户端工具")) + c.JSON(http.StatusInternalServerError, response.Err("pg_dump 不可用,请确保服务器已安装 PostgreSQL 客户端工具")) return } diff --git a/internal/apps/admin/system_config/routers.go b/internal/apps/admin/system_config/routers.go index 12b8d500..4ccf38ce 100644 --- a/internal/apps/admin/system_config/routers.go +++ b/internal/apps/admin/system_config/routers.go @@ -4,8 +4,7 @@ package system_config -import ( - "context" +import ("context" "encoding/json" "errors" "fmt" @@ -15,12 +14,12 @@ import ( "github.com/Rain-kl/Wavelet/internal/db" "github.com/Rain-kl/Wavelet/internal/model" "github.com/Rain-kl/Wavelet/internal/storage" - "github.com/Rain-kl/Wavelet/internal/util" "github.com/Rain-kl/Wavelet/pkg/logger" mail "github.com/Rain-kl/Wavelet/pkg/mail" "github.com/gin-gonic/gin" "gorm.io/gorm" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") const maskedConfigValue = "******" @@ -48,26 +47,26 @@ type UpdateSystemConfigRequest struct { // @Produce json // @Security SessionCookie // @Param request body system_config.CreateSystemConfigRequest true "创建请求参数" -// @Success 200 {object} util.ResponseAny{data=string} "创建成功" -// @Failure 400 {object} util.ResponseAny "参数错误或配置键已存在" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=string} "创建成功" +// @Failure 400 {object} response.Any "参数错误或配置键已存在" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/system-configs [post] func CreateSystemConfig(c *gin.Context) { var req CreateSystemConfigRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } // 检查配置键是否已存在 var existing model.SystemConfig if err := db.DB(c.Request.Context()).Where("key = ?", req.Key).First(&existing).Error; err == nil { - c.JSON(http.StatusBadRequest, util.Err(ConfigKeyExists)) + c.JSON(http.StatusBadRequest, response.Err(ConfigKeyExists)) return } else if !errors.Is(err, gorm.ErrRecordNotFound) { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } @@ -91,11 +90,11 @@ func CreateSystemConfig(c *gin.Context) { return nil }); err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } // ListSystemConfigs 获取系统配置列表 @@ -105,10 +104,10 @@ func CreateSystemConfig(c *gin.Context) { // @Produce json // @Security SessionCookie // @Param type query string false "配置类型(system/business)" -// @Success 200 {object} util.ResponseAny{data=[]model.SystemConfig} "系统配置列表" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=[]model.SystemConfig} "系统配置列表" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/system-configs [get] func ListSystemConfigs(c *gin.Context) { configType := c.Query("type") @@ -119,7 +118,7 @@ func ListSystemConfigs(c *gin.Context) { var configs []model.SystemConfig if err := query.Find(&configs).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } @@ -127,7 +126,7 @@ func ListSystemConfigs(c *gin.Context) { configs[i].Value = maskSensitiveConfig(configs[i].Key, configs[i].Value) } - c.JSON(http.StatusOK, util.OK(configs)) + c.JSON(http.StatusOK, response.OK(configs)) } // GetSystemConfig 获取单个系统配置 @@ -137,26 +136,26 @@ func ListSystemConfigs(c *gin.Context) { // @Produce json // @Security SessionCookie // @Param key path string true "配置键" -// @Success 200 {object} util.ResponseAny{data=model.SystemConfig} "系统配置详情" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 404 {object} util.ResponseAny "配置不存在" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=model.SystemConfig} "系统配置详情" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 404 {object} response.Any "配置不存在" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/system-configs/{key} [get] func GetSystemConfig(c *gin.Context) { var config model.SystemConfig if err := db.DB(c.Request.Context()).Where("key = ?", c.Param("key")).First(&config).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - c.JSON(http.StatusNotFound, util.Err(SystemConfigNotFound)) + c.JSON(http.StatusNotFound, response.Err(SystemConfigNotFound)) } else { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) } return } config.Value = maskSensitiveConfig(config.Key, config.Value) - c.JSON(http.StatusOK, util.OK(config)) + c.JSON(http.StatusOK, response.OK(config)) } // UpdateSystemConfig 更新系统配置 @@ -168,17 +167,17 @@ func GetSystemConfig(c *gin.Context) { // @Security SessionCookie // @Param key path string true "配置键" // @Param request body system_config.UpdateSystemConfigRequest true "更新请求参数" -// @Success 200 {object} util.ResponseAny{data=string} "更新成功" -// @Failure 400 {object} util.ResponseAny "参数错误" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 404 {object} util.ResponseAny "配置不存在" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=string} "更新成功" +// @Failure 400 {object} response.Any "参数错误" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 404 {object} response.Any "配置不存在" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/system-configs/{key} [put] func UpdateSystemConfig(c *gin.Context) { var req UpdateSystemConfigRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -188,9 +187,9 @@ func UpdateSystemConfig(c *gin.Context) { var config model.SystemConfig if err := db.DB(c.Request.Context()).Where("key = ?", key).First(&config).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - c.JSON(http.StatusNotFound, util.Err(SystemConfigNotFound)) + c.JSON(http.StatusNotFound, response.Err(SystemConfigNotFound)) } else { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) } return } @@ -204,7 +203,7 @@ func UpdateSystemConfig(c *gin.Context) { validatedVal, err := validateAndMergeStorageConfig(c.Request.Context(), req.Value, config.Value) if err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } req.Value = validatedVal @@ -251,7 +250,7 @@ func UpdateSystemConfig(c *gin.Context) { return nil }); err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } @@ -260,7 +259,7 @@ func UpdateSystemConfig(c *gin.Context) { storage.PublishCacheInvalidation(c.Request.Context()) } - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } // TestSMTPRequest 测试 SMTP 配置请求 @@ -287,13 +286,13 @@ type TestSMTPResponse struct { // @Produce json // @Security SessionCookie // @Param request body system_config.TestSMTPRequest true "测试请求参数" -// @Success 200 {object} util.ResponseAny{data=system_config.TestSMTPResponse} "测试执行完毕" -// @Failure 400 {object} util.ResponseAny "参数错误" +// @Success 200 {object} response.Any{data=system_config.TestSMTPResponse} "测试执行完毕" +// @Failure 400 {object} response.Any "参数错误" // @Router /api/v1/admin/system-configs/smtp/test [post] func TestSMTP(c *gin.Context) { var req TestSMTPRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -326,7 +325,7 @@ func TestSMTP(c *gin.Context) { resp.Error = err.Error() } - c.JSON(http.StatusOK, util.OK(resp)) + c.JSON(http.StatusOK, response.OK(resp)) } func maskSensitiveConfig(key, value string) string { diff --git a/internal/apps/admin/system_config/routers_test.go b/internal/apps/admin/system_config/routers_test.go index a2a3e3f9..ce2c85a5 100644 --- a/internal/apps/admin/system_config/routers_test.go +++ b/internal/apps/admin/system_config/routers_test.go @@ -4,8 +4,7 @@ package system_config -import ( - "bufio" +import ("bufio" "bytes" "context" "encoding/json" @@ -22,7 +21,8 @@ import ( "github.com/Rain-kl/Wavelet/internal/testhelper" "github.com/Rain-kl/Wavelet/internal/util" "github.com/gin-gonic/gin" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") const expectedDefaultConfigsCount = 30 @@ -133,7 +133,7 @@ func TestListSystemConfigs(t *testing.T) { t.Fatalf("expected 200 OK, got %d", w.Code) } - var resp util.ResponseAny + var resp response.Any _ = json.Unmarshal(w.Body.Bytes(), &resp) dataBytes, _ := json.Marshal(resp.Data) @@ -151,7 +151,7 @@ func TestListSystemConfigs(t *testing.T) { w := httptest.NewRecorder() router.ServeHTTP(w, req) - var resp util.ResponseAny + var resp response.Any _ = json.Unmarshal(w.Body.Bytes(), &resp) dataBytes, _ := json.Marshal(resp.Data) @@ -180,7 +180,7 @@ func TestGetSystemConfig(t *testing.T) { t.Errorf("expected 200 OK, got %d", w.Code) } - var resp util.ResponseAny + var resp response.Any _ = json.Unmarshal(w.Body.Bytes(), &resp) dataBytes, _ := json.Marshal(resp.Data) @@ -352,7 +352,7 @@ func TestTestSMTP(t *testing.T) { t.Fatalf("expected 200 OK, got %d. Body: %s", w.Code, w.Body.String()) } - var resp util.ResponseAny + var resp response.Any json.Unmarshal(w.Body.Bytes(), &resp) dataBytes, _ := json.Marshal(resp.Data) diff --git a/internal/apps/admin/task/routers.go b/internal/apps/admin/task/routers.go index 76cf8ae0..580a2261 100644 --- a/internal/apps/admin/task/routers.go +++ b/internal/apps/admin/task/routers.go @@ -4,8 +4,7 @@ package task -import ( - "fmt" +import ("fmt" "net/http" "strconv" "strings" @@ -16,11 +15,11 @@ import ( "github.com/Rain-kl/Wavelet/internal/task" taskhandlers "github.com/Rain-kl/Wavelet/internal/task/handlers" "github.com/Rain-kl/Wavelet/internal/task/scheduler" - "github.com/Rain-kl/Wavelet/internal/util" "github.com/Rain-kl/Wavelet/pkg/logger" "github.com/gin-gonic/gin" "github.com/robfig/cron/v3" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") func init() { taskhandlers.Register() @@ -32,12 +31,12 @@ func init() { // @Tags admin // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=[]task.TaskMeta} "任务类型列表" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" +// @Success 200 {object} response.Any{data=[]task.TaskMeta} "任务类型列表" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" // @Router /api/v1/admin/tasks/types [get] func ListTaskTypes(c *gin.Context) { - c.JSON(http.StatusOK, util.OK(task.GetDispatchableTasks())) + c.JSON(http.StatusOK, response.OK(task.GetDispatchableTasks())) } // DispatchTaskRequest 下发任务请求 @@ -57,22 +56,22 @@ type DispatchTaskRequest struct { // @Produce json // @Security SessionCookie // @Param request body DispatchTaskRequest true "任务请求参数" -// @Success 200 {object} util.ResponseAny{data=string} "任务已入队" -// @Failure 400 {object} util.ResponseAny "任务类型不存在或参数错误" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "任务入队失败" +// @Success 200 {object} response.Any{data=string} "任务已入队" +// @Failure 400 {object} response.Any "任务类型不存在或参数错误" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "任务入队失败" // @Router /api/v1/admin/tasks/dispatch [post] func DispatchTask(c *gin.Context) { var req DispatchTaskRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } meta := task.GetTaskMeta(req.TaskType) if meta == nil { - c.JSON(http.StatusBadRequest, util.Err(InvalidTaskType)) + c.JSON(http.StatusBadRequest, response.Err(InvalidTaskType)) return } @@ -83,17 +82,17 @@ func DispatchTask(c *gin.Context) { validated, err := task.ValidateAndNormalizePayload(meta.AsynqTask, payloadBytes) if err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } taskID, err := task.DispatchTask(c.Request.Context(), req.TaskType, validated, "manual") if err != nil { - c.JSON(http.StatusInternalServerError, util.Err(fmt.Sprintf("%s: %v", TaskDispatchFailed, err))) + c.JSON(http.StatusInternalServerError, response.Err(fmt.Sprintf("%s: %v", TaskDispatchFailed, err))) return } - c.JSON(http.StatusOK, util.OK(taskID)) + c.JSON(http.StatusOK, response.OK(taskID)) } // ListTaskExecutions 查询任务执行记录列表 @@ -106,14 +105,14 @@ func DispatchTask(c *gin.Context) { // @Param task_type query string false "任务类型筛选" // @Param page query int false "页码" default(1) // @Param page_size query int false "每页条数" default(20) -// @Success 200 {object} util.ResponseAny{data=object} "任务执行记录列表" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" +// @Success 200 {object} response.Any{data=object} "任务执行记录列表" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" // @Router /api/v1/admin/tasks/executions [get] func ListTaskExecutions(c *gin.Context) { var req model.ListTaskExecutionsRequest if err := c.ShouldBindQuery(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -125,11 +124,11 @@ func ListTaskExecutions(c *gin.Context) { executions, total, err := model.ListTaskExecutions(c.Request.Context(), req) if err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(gin.H{ + c.JSON(http.StatusOK, response.OK(gin.H{ "items": executions, "total": total, "page": req.Page, @@ -144,26 +143,26 @@ func ListTaskExecutions(c *gin.Context) { // @Produce json // @Security SessionCookie // @Param id path int true "任务执行记录 ID" -// @Success 200 {object} util.ResponseAny{data=model.TaskExecution} "任务执行详情" -// @Failure 400 {object} util.ResponseAny "参数错误" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 404 {object} util.ResponseAny "记录不存在" +// @Success 200 {object} response.Any{data=model.TaskExecution} "任务执行详情" +// @Failure 400 {object} response.Any "参数错误" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 404 {object} response.Any "记录不存在" // @Router /api/v1/admin/tasks/executions/{id} [get] func GetTaskExecution(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { - c.JSON(http.StatusBadRequest, util.Err(admin.InvalidTaskExecutionID)) + c.JSON(http.StatusBadRequest, response.Err(admin.InvalidTaskExecutionID)) return } execution, err := model.GetTaskExecutionByID(c.Request.Context(), id) if err != nil { - c.JSON(http.StatusNotFound, util.Err(TaskNotFound)) + c.JSON(http.StatusNotFound, response.Err(TaskNotFound)) return } - c.JSON(http.StatusOK, util.OK(execution)) + c.JSON(http.StatusOK, response.OK(execution)) } // RetryTask 重试失败的任务 @@ -173,17 +172,17 @@ func GetTaskExecution(c *gin.Context) { // @Produce json // @Security SessionCookie // @Param id path int true "任务执行记录 ID" -// @Success 200 {object} util.ResponseAny{data=string} "新任务的 TaskID" -// @Failure 400 {object} util.ResponseAny "任务不支持重试或参数错误" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 404 {object} util.ResponseAny "记录不存在" -// @Failure 500 {object} util.ResponseAny "重试失败" +// @Success 200 {object} response.Any{data=string} "新任务的 TaskID" +// @Failure 400 {object} response.Any "任务不支持重试或参数错误" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 404 {object} response.Any "记录不存在" +// @Failure 500 {object} response.Any "重试失败" // @Router /api/v1/admin/tasks/executions/{id}/retry [post] func RetryTask(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { - c.JSON(http.StatusBadRequest, util.Err(admin.InvalidTaskExecutionID)) + c.JSON(http.StatusBadRequest, response.Err(admin.InvalidTaskExecutionID)) return } @@ -192,16 +191,16 @@ func RetryTask(c *gin.Context) { errMsg := err.Error() switch { case strings.Contains(errMsg, "不存在"): - c.JSON(http.StatusNotFound, util.Err(errMsg)) + c.JSON(http.StatusNotFound, response.Err(errMsg)) case strings.Contains(errMsg, "只有失败的任务") || strings.Contains(errMsg, "不支持重试") || strings.Contains(errMsg, "已达到最大重试"): - c.JSON(http.StatusBadRequest, util.Err(errMsg)) + c.JSON(http.StatusBadRequest, response.Err(errMsg)) default: - c.JSON(http.StatusInternalServerError, util.Err(fmt.Sprintf("%s: %v", TaskRetryFailed, err))) + c.JSON(http.StatusInternalServerError, response.Err(fmt.Sprintf("%s: %v", TaskRetryFailed, err))) } return } - c.JSON(http.StatusOK, util.OK(newTaskID)) + c.JSON(http.StatusOK, response.OK(newTaskID)) } // ListSchedules 获取定时任务列表 @@ -210,17 +209,17 @@ func RetryTask(c *gin.Context) { // @Tags admin // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=[]model.Schedule} "定时任务列表" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" +// @Success 200 {object} response.Any{data=[]model.Schedule} "定时任务列表" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" // @Router /api/v1/admin/tasks/schedules [get] func ListSchedules(c *gin.Context) { schedules, err := model.ListSchedules(c.Request.Context()) if err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(schedules)) + c.JSON(http.StatusOK, response.OK(schedules)) } // CreateScheduleRequest 创建定时任务请求 @@ -240,29 +239,29 @@ type CreateScheduleRequest struct { // @Produce json // @Security SessionCookie // @Param request body CreateScheduleRequest true "创建定时任务请求参数" -// @Success 200 {object} util.ResponseAny{data=model.Schedule} "创建成功的定时任务信息" -// @Failure 400 {object} util.ResponseAny "Cron 表达式无效、异步任务类型不存在或参数错误" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "保存定时任务失败" +// @Success 200 {object} response.Any{data=model.Schedule} "创建成功的定时任务信息" +// @Failure 400 {object} response.Any "Cron 表达式无效、异步任务类型不存在或参数错误" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "保存定时任务失败" // @Router /api/v1/admin/tasks/schedules [post] func CreateSchedule(c *gin.Context) { var req CreateScheduleRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } // 校验 Cron 表达式 if _, err := cron.ParseStandard(req.Cron); err != nil { - c.JSON(http.StatusBadRequest, util.Err(InvalidCronExpression)) + c.JSON(http.StatusBadRequest, response.Err(InvalidCronExpression)) return } // 校验关联的异步任务类型 meta := task.GetTaskMeta(req.TaskType) if meta == nil { - c.JSON(http.StatusBadRequest, util.Err(InvalidTaskType)) + c.JSON(http.StatusBadRequest, response.Err(InvalidTaskType)) return } @@ -273,7 +272,7 @@ func CreateSchedule(c *gin.Context) { } validated, err := task.ValidateAndNormalizePayload(meta.AsynqTask, payloadBytes) if err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -286,7 +285,7 @@ func CreateSchedule(c *gin.Context) { } if err := model.CreateSchedule(c.Request.Context(), schedule); err != nil { - c.JSON(http.StatusInternalServerError, util.Err(fmt.Sprintf("%s: %v", ScheduleSaveFailed, err))) + c.JSON(http.StatusInternalServerError, response.Err(fmt.Sprintf("%s: %v", ScheduleSaveFailed, err))) return } @@ -295,7 +294,7 @@ func CreateSchedule(c *gin.Context) { logger.ErrorF(c.Request.Context(), "[TaskAdmin] 重载调度器失败: %v", err) } - c.JSON(http.StatusOK, util.OK(schedule)) + c.JSON(http.StatusOK, response.OK(schedule)) } // UpdateScheduleRequest 修改定时任务请求 @@ -316,43 +315,43 @@ type UpdateScheduleRequest struct { // @Security SessionCookie // @Param id path int true "定时任务 ID" // @Param request body UpdateScheduleRequest true "修改定时任务请求参数" -// @Success 200 {object} util.ResponseAny{data=model.Schedule} "修改后的定时任务信息" -// @Failure 400 {object} util.ResponseAny "Cron 表达式无效、参数错误" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 404 {object} util.ResponseAny "定时任务不存在" -// @Failure 500 {object} util.ResponseAny "修改定时任务失败" +// @Success 200 {object} response.Any{data=model.Schedule} "修改后的定时任务信息" +// @Failure 400 {object} response.Any "Cron 表达式无效、参数错误" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 404 {object} response.Any "定时任务不存在" +// @Failure 500 {object} response.Any "修改定时任务失败" // @Router /api/v1/admin/tasks/schedules/{id} [put] func UpdateSchedule(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { - c.JSON(http.StatusBadRequest, util.Err("无效的定时任务ID")) + c.JSON(http.StatusBadRequest, response.Err("无效的定时任务ID")) return } var req UpdateScheduleRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } // 检查定时任务是否存在 schedule, err := model.GetScheduleByID(c.Request.Context(), id) if err != nil { - c.JSON(http.StatusNotFound, util.Err(ScheduleNotFound)) + c.JSON(http.StatusNotFound, response.Err(ScheduleNotFound)) return } // 校验 Cron 表达式 if _, err := cron.ParseStandard(req.Cron); err != nil { - c.JSON(http.StatusBadRequest, util.Err(InvalidCronExpression)) + c.JSON(http.StatusBadRequest, response.Err(InvalidCronExpression)) return } // 校验关联的异步任务类型 meta := task.GetTaskMeta(req.TaskType) if meta == nil { - c.JSON(http.StatusBadRequest, util.Err(InvalidTaskType)) + c.JSON(http.StatusBadRequest, response.Err(InvalidTaskType)) return } @@ -363,7 +362,7 @@ func UpdateSchedule(c *gin.Context) { } validated, err := task.ValidateAndNormalizePayload(meta.AsynqTask, payloadBytes) if err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -374,7 +373,7 @@ func UpdateSchedule(c *gin.Context) { schedule.IsActive = *req.IsActive if err := model.UpdateSchedule(c.Request.Context(), schedule); err != nil { - c.JSON(http.StatusInternalServerError, util.Err(fmt.Sprintf("%s: %v", ScheduleSaveFailed, err))) + c.JSON(http.StatusInternalServerError, response.Err(fmt.Sprintf("%s: %v", ScheduleSaveFailed, err))) return } @@ -383,7 +382,7 @@ func UpdateSchedule(c *gin.Context) { logger.ErrorF(c.Request.Context(), "[TaskAdmin] 重载调度器失败: %v", err) } - c.JSON(http.StatusOK, util.OK(schedule)) + c.JSON(http.StatusOK, response.OK(schedule)) } // DeleteSchedule 删除定时任务 @@ -393,21 +392,21 @@ func UpdateSchedule(c *gin.Context) { // @Produce json // @Security SessionCookie // @Param id path int true "定时任务 ID" -// @Success 200 {object} util.ResponseAny{data=string} "删除结果" -// @Failure 400 {object} util.ResponseAny "参数错误" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "删除定时任务失败" +// @Success 200 {object} response.Any{data=string} "删除结果" +// @Failure 400 {object} response.Any "参数错误" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "删除定时任务失败" // @Router /api/v1/admin/tasks/schedules/{id} [delete] func DeleteSchedule(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { - c.JSON(http.StatusBadRequest, util.Err("无效的定时任务ID")) + c.JSON(http.StatusBadRequest, response.Err("无效的定时任务ID")) return } if err := model.DeleteSchedule(c.Request.Context(), id); err != nil { - c.JSON(http.StatusInternalServerError, util.Err(fmt.Sprintf("%s: %v", ScheduleDeleteFailed, err))) + c.JSON(http.StatusInternalServerError, response.Err(fmt.Sprintf("%s: %v", ScheduleDeleteFailed, err))) return } @@ -416,5 +415,5 @@ func DeleteSchedule(c *gin.Context) { logger.ErrorF(c.Request.Context(), "[TaskAdmin] 重载调度器失败: %v", err) } - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } diff --git a/internal/apps/admin/task/routers_test.go b/internal/apps/admin/task/routers_test.go index bdc2939c..a3f8a268 100644 --- a/internal/apps/admin/task/routers_test.go +++ b/internal/apps/admin/task/routers_test.go @@ -4,8 +4,7 @@ package task -import ( - "bytes" +import ("bytes" "context" "encoding/json" "fmt" @@ -26,7 +25,8 @@ import ( "github.com/hibiken/asynq" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") func setupTaskTestEnvironment(t *testing.T) func() { _, mr, cleanup := testhelper.SetupTestEnvironment(t) @@ -78,7 +78,7 @@ func TestListTaskTypes(t *testing.T) { t.Errorf("expected 200 OK, got %d", w.Code) } - var resp util.ResponseAny + var resp response.Any _ = json.Unmarshal(w.Body.Bytes(), &resp) dataBytes, _ := json.Marshal(resp.Data) @@ -126,7 +126,7 @@ func TestDispatchTask(t *testing.T) { assert.Equal(t, http.StatusOK, w.Code, "Body: %s", w.Body.String()) - var resp util.ResponseAny + var resp response.Any _ = json.Unmarshal(w.Body.Bytes(), &resp) assert.Empty(t, resp.ErrorMsg) assert.NotNil(t, resp.Data) @@ -150,7 +150,7 @@ func TestDispatchTask(t *testing.T) { assert.Equal(t, http.StatusOK, w.Code, "Body: %s", w.Body.String()) - var resp util.ResponseAny + var resp response.Any json.Unmarshal(w.Body.Bytes(), &resp) assert.Empty(t, resp.ErrorMsg) assert.NotNil(t, resp.Data) @@ -168,7 +168,7 @@ func TestDispatchTask(t *testing.T) { router.ServeHTTP(w, req) assert.Equal(t, http.StatusBadRequest, w.Code) - var resp util.ResponseAny + var resp response.Any json.Unmarshal(w.Body.Bytes(), &resp) assert.Contains(t, resp.ErrorMsg, "无效的 JSON 格式") }) @@ -185,7 +185,7 @@ func TestDispatchTask(t *testing.T) { router.ServeHTTP(w, req) assert.Equal(t, http.StatusBadRequest, w.Code) - var resp util.ResponseAny + var resp response.Any json.Unmarshal(w.Body.Bytes(), &resp) assert.Contains(t, resp.ErrorMsg, "不能为空") }) @@ -202,7 +202,7 @@ func TestDispatchTask(t *testing.T) { assert.Equal(t, http.StatusBadRequest, w.Code) - var resp util.ResponseAny + var resp response.Any json.Unmarshal(w.Body.Bytes(), &resp) assert.Equal(t, InvalidTaskType, resp.ErrorMsg) }) @@ -244,7 +244,7 @@ func TestListTaskExecutions(t *testing.T) { assert.Equal(t, http.StatusOK, w.Code) - var resp util.ResponseAny + var resp response.Any json.Unmarshal(w.Body.Bytes(), &resp) dataBytes, _ := json.Marshal(resp.Data) @@ -261,7 +261,7 @@ func TestListTaskExecutions(t *testing.T) { assert.Equal(t, http.StatusOK, w.Code) - var resp util.ResponseAny + var resp response.Any json.Unmarshal(w.Body.Bytes(), &resp) dataBytes, _ := json.Marshal(resp.Data) @@ -278,7 +278,7 @@ func TestListTaskExecutions(t *testing.T) { assert.Equal(t, http.StatusOK, w.Code) - var resp util.ResponseAny + var resp response.Any json.Unmarshal(w.Body.Bytes(), &resp) dataBytes, _ := json.Marshal(resp.Data) @@ -295,7 +295,7 @@ func TestListTaskExecutions(t *testing.T) { assert.Equal(t, http.StatusOK, w.Code) - var resp util.ResponseAny + var resp response.Any json.Unmarshal(w.Body.Bytes(), &resp) dataBytes, _ := json.Marshal(resp.Data) @@ -312,7 +312,7 @@ func TestListTaskExecutions(t *testing.T) { assert.Equal(t, http.StatusOK, w.Code) - var resp util.ResponseAny + var resp response.Any json.Unmarshal(w.Body.Bytes(), &resp) dataBytes, _ := json.Marshal(resp.Data) @@ -355,7 +355,7 @@ func TestGetTaskExecution(t *testing.T) { assert.Equal(t, http.StatusOK, w.Code) - var resp util.ResponseAny + var resp response.Any json.Unmarshal(w.Body.Bytes(), &resp) dataBytes, _ := json.Marshal(resp.Data) @@ -419,7 +419,7 @@ func TestRetryTask(t *testing.T) { assert.Equal(t, http.StatusOK, w.Code) - var resp util.ResponseAny + var resp response.Any json.Unmarshal(w.Body.Bytes(), &resp) assert.Empty(t, resp.ErrorMsg) assert.NotNil(t, resp.Data) diff --git a/internal/apps/admin/template/routers.go b/internal/apps/admin/template/routers.go index 21d7971a..7580aa59 100644 --- a/internal/apps/admin/template/routers.go +++ b/internal/apps/admin/template/routers.go @@ -3,16 +3,15 @@ package template -import ( - "errors" +import ("errors" "net/http" "github.com/Rain-kl/Wavelet/internal/db" "github.com/Rain-kl/Wavelet/internal/model" - "github.com/Rain-kl/Wavelet/internal/util" "github.com/gin-gonic/gin" "gorm.io/gorm" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") // CreateTemplateRequest 创建模板请求 type CreateTemplateRequest struct { @@ -41,26 +40,26 @@ type UpdateTemplateRequest struct { // @Produce json // @Security SessionCookie // @Param request body template.CreateTemplateRequest true "创建请求参数" -// @Success 200 {object} util.ResponseAny{data=string} "创建成功" -// @Failure 400 {object} util.ResponseAny "参数错误或模板标识符已存在" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=string} "创建成功" +// @Failure 400 {object} response.Any "参数错误或模板标识符已存在" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/templates [post] func CreateTemplate(c *gin.Context) { var req CreateTemplateRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } // 检查模板 Key 是否已存在 var existing model.Template if err := db.DB(c.Request.Context()).Where("key = ?", req.Key).First(&existing).Error; err == nil { - c.JSON(http.StatusBadRequest, util.Err(TemplateKeyExists)) + c.JSON(http.StatusBadRequest, response.Err(TemplateKeyExists)) return } else if !errors.Is(err, gorm.ErrRecordNotFound) { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } @@ -75,16 +74,16 @@ func CreateTemplate(c *gin.Context) { } if err := tmpl.Validate(); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } if err := db.DB(c.Request.Context()).Create(&tmpl).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(tmpl)) + c.JSON(http.StatusOK, response.OK(tmpl)) } // ListTemplates 获取模板列表 @@ -93,19 +92,19 @@ func CreateTemplate(c *gin.Context) { // @Tags admin // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=[]model.Template} "模板列表" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=[]model.Template} "模板列表" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/templates [get] func ListTemplates(c *gin.Context) { var templates []model.Template if err := db.DB(c.Request.Context()).Order("is_system DESC, created_at DESC").Find(&templates).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(templates)) + c.JSON(http.StatusOK, response.OK(templates)) } // GetTemplate 获取单个模板 @@ -115,24 +114,24 @@ func ListTemplates(c *gin.Context) { // @Produce json // @Security SessionCookie // @Param key path string true "模板标识符" -// @Success 200 {object} util.ResponseAny{data=model.Template} "模板详情" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 404 {object} util.ResponseAny "模板不存在" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=model.Template} "模板详情" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 404 {object} response.Any "模板不存在" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/templates/{key} [get] func GetTemplate(c *gin.Context) { var tmpl model.Template if err := db.DB(c.Request.Context()).Where("key = ?", c.Param("key")).First(&tmpl).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - c.JSON(http.StatusNotFound, util.Err(TemplateNotFound)) + c.JSON(http.StatusNotFound, response.Err(TemplateNotFound)) } else { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) } return } - c.JSON(http.StatusOK, util.OK(tmpl)) + c.JSON(http.StatusOK, response.OK(tmpl)) } // UpdateTemplate 更新模板 @@ -144,17 +143,17 @@ func GetTemplate(c *gin.Context) { // @Security SessionCookie // @Param key path string true "模板标识符" // @Param request body template.UpdateTemplateRequest true "更新请求参数" -// @Success 200 {object} util.ResponseAny{data=model.Template} "更新成功" -// @Failure 400 {object} util.ResponseAny "参数错误" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 404 {object} util.ResponseAny "模板不存在" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=model.Template} "更新成功" +// @Failure 400 {object} response.Any "参数错误" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 404 {object} response.Any "模板不存在" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/templates/{key} [put] func UpdateTemplate(c *gin.Context) { var req UpdateTemplateRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -164,9 +163,9 @@ func UpdateTemplate(c *gin.Context) { var tmpl model.Template if err := db.DB(c.Request.Context()).Where("key = ?", key).First(&tmpl).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - c.JSON(http.StatusNotFound, util.Err(TemplateNotFound)) + c.JSON(http.StatusNotFound, response.Err(TemplateNotFound)) } else { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) } return } @@ -178,16 +177,16 @@ func UpdateTemplate(c *gin.Context) { tmpl.Description = req.Description if err := tmpl.Validate(); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } if err := db.DB(c.Request.Context()).Save(&tmpl).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(tmpl)) + c.JSON(http.StatusOK, response.OK(tmpl)) } // DeleteTemplate 删除模板 @@ -197,12 +196,12 @@ func UpdateTemplate(c *gin.Context) { // @Produce json // @Security SessionCookie // @Param key path string true "模板标识符" -// @Success 200 {object} util.ResponseAny{data=string} "删除成功" -// @Failure 400 {object} util.ResponseAny "不可删除系统模板" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 404 {object} util.ResponseAny "模板不存在" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=string} "删除成功" +// @Failure 400 {object} response.Any "不可删除系统模板" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 404 {object} response.Any "模板不存在" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/templates/{key} [delete] func DeleteTemplate(c *gin.Context) { key := c.Param("key") @@ -211,23 +210,23 @@ func DeleteTemplate(c *gin.Context) { var tmpl model.Template if err := db.DB(c.Request.Context()).Where("key = ?", key).First(&tmpl).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - c.JSON(http.StatusNotFound, util.Err(TemplateNotFound)) + c.JSON(http.StatusNotFound, response.Err(TemplateNotFound)) } else { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) } return } // 限制系统模板删除 if tmpl.IsSystem { - c.JSON(http.StatusBadRequest, util.Err(SystemTemplateCannotDelete)) + c.JSON(http.StatusBadRequest, response.Err(SystemTemplateCannotDelete)) return } if err := db.DB(c.Request.Context()).Delete(&tmpl).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } diff --git a/internal/apps/admin/template/routers_test.go b/internal/apps/admin/template/routers_test.go index 9cc86686..b78f72c9 100644 --- a/internal/apps/admin/template/routers_test.go +++ b/internal/apps/admin/template/routers_test.go @@ -3,8 +3,7 @@ package template -import ( - "bytes" +import ("bytes" "encoding/json" "net/http" "net/http/httptest" @@ -15,7 +14,8 @@ import ( "github.com/Rain-kl/Wavelet/internal/testhelper" "github.com/Rain-kl/Wavelet/internal/util" "github.com/gin-gonic/gin" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") func setupTestRouter(authUser *model.User) *gin.Engine { gin.SetMode(gin.TestMode) @@ -122,7 +122,7 @@ func TestListTemplates(t *testing.T) { t.Fatalf("expected 200 OK, got %d", w.Code) } - var resp util.ResponseAny + var resp response.Any _ = json.Unmarshal(w.Body.Bytes(), &resp) dataBytes, _ := json.Marshal(resp.Data) diff --git a/internal/apps/admin/updater/routers.go b/internal/apps/admin/updater/routers.go index f359d0af..3e5ba0da 100644 --- a/internal/apps/admin/updater/routers.go +++ b/internal/apps/admin/updater/routers.go @@ -3,15 +3,14 @@ package updater -import ( - "context" +import ("context" "net/http" "time" - "github.com/Rain-kl/Wavelet/internal/util" "github.com/Rain-kl/Wavelet/pkg/logger" "github.com/gin-gonic/gin" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") // GetUpdateStatus 获取应用更新状态 // @Summary 获取应用更新状态 @@ -19,19 +18,19 @@ import ( // @Tags admin // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=updater.Status} "更新状态" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "查询失败" +// @Success 200 {object} response.Any{data=updater.Status} "更新状态" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "查询失败" // @Router /api/v1/admin/update [get] func GetUpdateStatus(c *gin.Context) { status, _, err := defaultManager.status(c.Request.Context()) if err != nil { logger.ErrorF(c.Request.Context(), "[Updater] check release failed: %v", err) - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(status)) + c.JSON(http.StatusOK, response.OK(status)) } // ApplyUpdate 下载并应用应用更新 @@ -40,22 +39,22 @@ func GetUpdateStatus(c *gin.Context) { // @Tags admin // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny "升级已准备并即将重启" -// @Failure 400 {object} util.ResponseAny "当前版本不可升级" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "升级准备失败" +// @Success 200 {object} response.Any "升级已准备并即将重启" +// @Failure 400 {object} response.Any "当前版本不可升级" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "升级准备失败" // @Router /api/v1/admin/update/apply [post] func ApplyUpdate(c *gin.Context) { executable, stagedBinary, err := defaultManager.prepareUpgrade(c.Request.Context()) if err != nil { logger.ErrorF(c.Request.Context(), "[Updater] prepare upgrade failed: %v", err) - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } logger.InfoF(c.Request.Context(), "[Updater] upgrade prepared; restarting with %s", stagedBinary) - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) go func() { time.Sleep(time.Second) diff --git a/internal/apps/admin/user/routers.go b/internal/apps/admin/user/routers.go index 37e1f753..00b6b096 100644 --- a/internal/apps/admin/user/routers.go +++ b/internal/apps/admin/user/routers.go @@ -4,8 +4,7 @@ package user -import ( - "net/http" +import ("net/http" "strconv" "strings" "time" @@ -17,7 +16,8 @@ import ( "github.com/Rain-kl/Wavelet/internal/util" "github.com/gin-gonic/gin" "gorm.io/gorm" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") // minPasswordLength 密码最小长度 const minPasswordLength = 8 @@ -57,7 +57,7 @@ type listUsersResponse struct { func parseUserID(c *gin.Context) (uint64, bool) { id, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil || id == 0 { - c.JSON(http.StatusBadRequest, util.Err(userNotFound)) + c.JSON(http.StatusBadRequest, response.Err(userNotFound)) return 0, false } return id, true @@ -90,17 +90,17 @@ func toUser(u model.User) user { // @Produce json // @Security SessionCookie // @Param request query listUsersRequest true "查询参数" -// @Success 200 {object} util.ResponseAny{data=user.listUsersResponse} "用户列表" -// @Failure 400 {object} util.ResponseAny "参数错误" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=user.listUsersResponse} "用户列表" +// @Failure 400 {object} response.Any "参数错误" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/users [get] // ListUsers 获取用户列表 func ListUsers(c *gin.Context) { var req listUsersRequest if err := c.ShouldBindQuery(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -120,7 +120,7 @@ func ListUsers(c *gin.Context) { } if err := query.Count(&total).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } @@ -132,11 +132,11 @@ func ListUsers(c *gin.Context) { Offset(offset). Limit(req.PageSize). Find(&users).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(listUsersResponse{ + c.JSON(http.StatusOK, response.OK(listUsersResponse{ Users: users, Total: total, })) @@ -149,12 +149,12 @@ func ListUsers(c *gin.Context) { // @Produce json // @Security SessionCookie // @Param id path int true "用户 ID" -// @Success 200 {object} util.ResponseAny{data=user.user} "用户详情" -// @Failure 400 {object} util.ResponseAny "参数错误" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 404 {object} util.ResponseAny "用户不存在" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=user.user} "用户详情" +// @Failure 400 {object} response.Any "参数错误" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 404 {object} response.Any "用户不存在" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/users/{id} [get] func GetUser(c *gin.Context) { id, ok := parseUserID(c) @@ -169,14 +169,14 @@ func GetUser(c *gin.Context) { Where("id = ?", id). First(&targetUser).Error; err != nil { if err == gorm.ErrRecordNotFound { - c.JSON(http.StatusNotFound, util.Err(userNotFound)) + c.JSON(http.StatusNotFound, response.Err(userNotFound)) return } - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(toUser(targetUser))) + c.JSON(http.StatusOK, response.OK(toUser(targetUser))) } // updateUserStatusRequest 更新用户状态请求 @@ -193,17 +193,17 @@ type updateUserStatusRequest struct { // @Security SessionCookie // @Param id path int true "用户 ID" // @Param request body updateUserStatusRequest true "状态参数" -// @Success 200 {object} util.ResponseAny{data=string} "更新成功" -// @Failure 400 {object} util.ResponseAny "参数错误" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限或尝试禁用管理员" -// @Failure 404 {object} util.ResponseAny "用户不存在" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=string} "更新成功" +// @Failure 400 {object} response.Any "参数错误" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限或尝试禁用管理员" +// @Failure 404 {object} response.Any "用户不存在" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/users/{id}/status [put] func UpdateUserStatus(c *gin.Context) { var req updateUserStatusRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -222,15 +222,15 @@ func UpdateUserStatus(c *gin.Context) { Where("id = ?", id). First(&targetUser).Error; err != nil { if err == gorm.ErrRecordNotFound { - c.JSON(http.StatusNotFound, util.Err(userNotFound)) + c.JSON(http.StatusNotFound, response.Err(userNotFound)) return } - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } if !req.IsActive && targetUser.IsAdmin { - c.JSON(http.StatusForbidden, util.Err(cannotDisable)) + c.JSON(http.StatusForbidden, response.Err(cannotDisable)) return } @@ -238,11 +238,11 @@ func UpdateUserStatus(c *gin.Context) { Model(&model.User{}). Where("id = ?", id). Update("is_active", req.IsActive).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(updateUserFailed)) + c.JSON(http.StatusInternalServerError, response.Err(updateUserFailed)) return } - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } // DeleteUser 删除用户 @@ -252,12 +252,12 @@ func UpdateUserStatus(c *gin.Context) { // @Produce json // @Security SessionCookie // @Param id path int true "用户 ID" -// @Success 200 {object} util.ResponseAny{data=string} "删除成功" -// @Failure 400 {object} util.ResponseAny "参数错误" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限、尝试删除管理员或当前用户" -// @Failure 404 {object} util.ResponseAny "用户不存在" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=string} "删除成功" +// @Failure 400 {object} response.Any "参数错误" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限、尝试删除管理员或当前用户" +// @Failure 404 {object} response.Any "用户不存在" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/users/{id} [delete] func DeleteUser(c *gin.Context) { id, ok := parseUserID(c) @@ -267,7 +267,7 @@ func DeleteUser(c *gin.Context) { currUser, _ := util.GetFromContext[*model.User](c, oauth.UserObjKey) if currUser != nil && currUser.ID == id { - c.JSON(http.StatusForbidden, util.Err(cannotDeleteSelf)) + c.JSON(http.StatusForbidden, response.Err(cannotDeleteSelf)) return } @@ -281,15 +281,15 @@ func DeleteUser(c *gin.Context) { Where("id = ?", id). First(&targetUser).Error; err != nil { if err == gorm.ErrRecordNotFound { - c.JSON(http.StatusNotFound, util.Err(userNotFound)) + c.JSON(http.StatusNotFound, response.Err(userNotFound)) return } - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } if targetUser.IsAdmin { - c.JSON(http.StatusForbidden, util.Err(cannotDelete)) + c.JSON(http.StatusForbidden, response.Err(cannotDelete)) return } @@ -302,11 +302,11 @@ func DeleteUser(c *gin.Context) { } return tx.Where("id = ?", id).Delete(&model.User{}).Error }); err != nil { - c.JSON(http.StatusInternalServerError, util.Err(deleteUserFailed)) + c.JSON(http.StatusInternalServerError, response.Err(deleteUserFailed)) return } - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } // createUserRequest 创建用户请求 @@ -327,16 +327,16 @@ type createUserRequest struct { // @Produce json // @Security SessionCookie // @Param request body user.createUserRequest true "创建用户参数" -// @Success 200 {object} util.ResponseAny{data=user.user} "创建成功" -// @Failure 400 {object} util.ResponseAny "参数错误或用户名已存在" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=user.user} "创建成功" +// @Failure 400 {object} response.Any "参数错误或用户名已存在" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/users [post] func CreateUser(c *gin.Context) { var req createUserRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -346,36 +346,36 @@ func CreateUser(c *gin.Context) { req.Email = strings.TrimSpace(req.Email) if req.Username == "" { - c.JSON(http.StatusBadRequest, util.Err(usernameRequired)) + c.JSON(http.StatusBadRequest, response.Err(usernameRequired)) return } if req.Email == "" { - c.JSON(http.StatusBadRequest, util.Err(emailRequired)) + c.JSON(http.StatusBadRequest, response.Err(emailRequired)) return } if len(req.Password) < minPasswordLength { - c.JSON(http.StatusBadRequest, util.Err(passwordTooShort)) + c.JSON(http.StatusBadRequest, response.Err(passwordTooShort)) return } ctx := c.Request.Context() var count int64 if err := db.DB(ctx).Model(&model.User{}).Where("username = ?", req.Username).Count(&count).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } if count > 0 { - c.JSON(http.StatusBadRequest, util.Err(usernameExists)) + c.JSON(http.StatusBadRequest, response.Err(usernameExists)) return } var emailCount int64 if err := db.DB(ctx).Model(&model.User{}).Where("email = ?", req.Email).Count(&emailCount).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } if emailCount > 0 { - c.JSON(http.StatusBadRequest, util.Err(emailExists)) + c.JSON(http.StatusBadRequest, response.Err(emailExists)) return } @@ -393,14 +393,14 @@ func CreateUser(c *gin.Context) { } if err := newUser.SetEncryptedPassword(req.Password); err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } if err := db.DB(ctx).Create(&newUser).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(toUser(newUser))) + c.JSON(http.StatusOK, response.OK(toUser(newUser))) } diff --git a/internal/apps/admin/user/routers_test.go b/internal/apps/admin/user/routers_test.go index d499e9f9..697959c8 100644 --- a/internal/apps/admin/user/routers_test.go +++ b/internal/apps/admin/user/routers_test.go @@ -4,8 +4,7 @@ package user -import ( - "bytes" +import ("bytes" "encoding/json" "net/http" "net/http/httptest" @@ -17,7 +16,8 @@ import ( "github.com/Rain-kl/Wavelet/internal/testhelper" "github.com/Rain-kl/Wavelet/internal/util" "github.com/gin-gonic/gin" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") func setupTestRouter(authUser *model.User) *gin.Engine { gin.SetMode(gin.TestMode) @@ -90,7 +90,7 @@ func TestListUsers(t *testing.T) { t.Errorf("expected 200 OK, got %d. Body: %s", w.Code, w.Body.String()) } - var resp util.ResponseAny + var resp response.Any if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil { t.Fatalf("failed to parse response: %v", err) } @@ -119,7 +119,7 @@ func TestListUsers(t *testing.T) { w := httptest.NewRecorder() router.ServeHTTP(w, req) - var resp util.ResponseAny + var resp response.Any _ = json.Unmarshal(w.Body.Bytes(), &resp) dataBytes, _ := json.Marshal(resp.Data) @@ -136,7 +136,7 @@ func TestListUsers(t *testing.T) { w := httptest.NewRecorder() router.ServeHTTP(w, req) - var resp util.ResponseAny + var resp response.Any _ = json.Unmarshal(w.Body.Bytes(), &resp) dataBytes, _ := json.Marshal(resp.Data) @@ -194,7 +194,7 @@ func TestGetUser(t *testing.T) { t.Fatalf("expected 200 OK, got %d. Body: %s", w.Code, w.Body.String()) } - var resp util.ResponseAny + var resp response.Any if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil { t.Fatalf("failed to parse response: %v", err) } @@ -280,7 +280,7 @@ func TestUpdateUserStatus(t *testing.T) { t.Errorf("expected 403 Forbidden, got %d. Body: %s", w.Code, w.Body.String()) } - var resp util.ResponseAny + var resp response.Any _ = json.Unmarshal(w.Body.Bytes(), &resp) if resp.ErrorMsg != cannotDisable { t.Errorf("expected error message '%s', got '%s'", cannotDisable, resp.ErrorMsg) @@ -327,7 +327,7 @@ func TestCreateUser(t *testing.T) { t.Errorf("expected 200 OK, got %d. Body: %s", w.Code, w.Body.String()) } - var resp util.ResponseAny + var resp response.Any if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil { t.Fatalf("failed to parse response: %v", err) } @@ -386,7 +386,7 @@ func TestCreateUser(t *testing.T) { t.Errorf("expected 400 Bad Request, got %d. Body: %s", w.Code, w.Body.String()) } - var resp util.ResponseAny + var resp response.Any _ = json.Unmarshal(w.Body.Bytes(), &resp) if resp.ErrorMsg != usernameExists { t.Errorf("expected error '%s', got '%s'", usernameExists, resp.ErrorMsg) @@ -419,7 +419,7 @@ func TestCreateUser(t *testing.T) { t.Errorf("expected 400 Bad Request, got %d. Body: %s", w.Code, w.Body.String()) } - var resp util.ResponseAny + var resp response.Any _ = json.Unmarshal(w.Body.Bytes(), &resp) if resp.ErrorMsg != emailExists { t.Errorf("expected error '%s', got '%s'", emailExists, resp.ErrorMsg) diff --git a/internal/apps/cap/middleware.go b/internal/apps/cap/middleware.go index cf55d7af..b3893b65 100644 --- a/internal/apps/cap/middleware.go +++ b/internal/apps/cap/middleware.go @@ -3,13 +3,12 @@ package cap -import ( - "net/http" +import ("net/http" - "github.com/Rain-kl/Wavelet/internal/util" caputil "github.com/Rain-kl/Wavelet/internal/service/cap" "github.com/gin-gonic/gin" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") // VerifyMiddleware returns a Gin middleware that checks and consumes the X-Cap-Token header. // enabledFunc is an optional callback allowing dynamic check of whether captcha protection is turned on. @@ -22,13 +21,13 @@ func VerifyMiddleware(mgr *caputil.Manager, scope string, enabledFunc func() boo token := c.GetHeader("X-Cap-Token") if token == "" { - c.AbortWithStatusJSON(http.StatusUnauthorized, util.Err(errCapTokenMissing)) + c.AbortWithStatusJSON(http.StatusUnauthorized, response.Err(errCapTokenMissing)) return } valid, err := mgr.VerifyToken(c.Request.Context(), token, scope) if err != nil || !valid { - c.AbortWithStatusJSON(http.StatusUnauthorized, util.Err(errCapTokenInvalidOrExpired)) + c.AbortWithStatusJSON(http.StatusUnauthorized, response.Err(errCapTokenInvalidOrExpired)) return } diff --git a/internal/apps/cap/routers.go b/internal/apps/cap/routers.go index 1ed80974..fddc8511 100644 --- a/internal/apps/cap/routers.go +++ b/internal/apps/cap/routers.go @@ -28,7 +28,7 @@ type redeemRequest struct { // @Produce json // @Param request body challengeRequest false "可选范围限制参数" // @Success 200 {object} cap.ChallengeResponse "成功返回 PoW 难题" -// @Failure 500 {object} cap.RedeemResponse "内部服务错误" +// @Failure 500 {object} capService.RedeemResponse "内部服务错误" // @Router /api/cap/challenge [post] func Challenge(c *gin.Context) { var req challengeRequest @@ -58,9 +58,9 @@ func Challenge(c *gin.Context) { // @Accept json // @Produce json // @Param request body redeemRequest true "难题 Token 与解答 solutions 数组" -// @Success 200 {object} cap.RedeemResponse "核销成功,返回 X-Cap-Token" -// @Failure 400 {object} cap.RedeemResponse "参数错误或核销失败" -// @Failure 500 {object} cap.RedeemResponse "内部服务错误" +// @Success 200 {object} capService.RedeemResponse "核销成功,返回 X-Cap-Token" +// @Failure 400 {object} capService.RedeemResponse "参数错误或核销失败" +// @Failure 500 {object} capService.RedeemResponse "内部服务错误" // @Router /api/cap/redeem [post] func Redeem(c *gin.Context) { var req redeemRequest diff --git a/internal/apps/cap/routers_test.go b/internal/apps/cap/routers_test.go index 44f2b41e..e3531077 100644 --- a/internal/apps/cap/routers_test.go +++ b/internal/apps/cap/routers_test.go @@ -3,8 +3,7 @@ package cap -import ( - "bytes" +import ("bytes" "context" "encoding/json" "net/http" @@ -14,11 +13,11 @@ import ( "github.com/Rain-kl/Wavelet/internal/db" "github.com/Rain-kl/Wavelet/internal/model" "github.com/Rain-kl/Wavelet/internal/testhelper" - "github.com/Rain-kl/Wavelet/internal/util" capUtil "github.com/Rain-kl/Wavelet/internal/service/cap" pkgcap "github.com/Rain-kl/Wavelet/pkg/cap" "github.com/gin-gonic/gin" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") func TestCapEndpointsAndMiddleware(t *testing.T) { sqliteDB, _, cleanup := testhelper.SetupTestEnvironment(t) @@ -42,7 +41,7 @@ func TestCapEndpointsAndMiddleware(t *testing.T) { } return enabled }), func(c *gin.Context) { - c.JSON(http.StatusOK, util.OK("login success")) + c.JSON(http.StatusOK, response.OK("login success")) }) // 1. Test challenge generation diff --git a/internal/apps/config/routers.go b/internal/apps/config/routers.go index 12355cd5..8f693cb0 100644 --- a/internal/apps/config/routers.go +++ b/internal/apps/config/routers.go @@ -5,13 +5,12 @@ // Package config 提供公开配置查询接口 package config -import ( - "net/http" +import ("net/http" "github.com/Rain-kl/Wavelet/internal/model" - "github.com/Rain-kl/Wavelet/internal/util" "github.com/gin-gonic/gin" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") // GetPublicConfig 获取公共配置 // @Summary 获取公共配置 @@ -19,22 +18,22 @@ import ( // @Tags config // @Accept json // @Produce json -// @Success 200 {object} util.ResponseAny +// @Success 200 {object} response.Any // @Router /api/v1/config/public [get] func GetPublicConfig(c *gin.Context) { ctx := c.Request.Context() configs, err := model.ListVisibleSystemConfigs(ctx) if err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - response := make(map[string]string, len(configs)) + resp := make(map[string]string, len(configs)) for _, config := range configs { - response[config.Key] = config.Value + resp[config.Key] = config.Value } - c.JSON(http.StatusOK, util.OK(response)) + c.JSON(http.StatusOK, response.OK(resp)) } // GetRobotsTXT 动态生成 robots.txt diff --git a/internal/apps/config/routers_test.go b/internal/apps/config/routers_test.go index 8e07c64d..28467b97 100644 --- a/internal/apps/config/routers_test.go +++ b/internal/apps/config/routers_test.go @@ -4,17 +4,16 @@ package config -import ( - "encoding/json" +import ("encoding/json" "net/http" "net/http/httptest" "testing" "github.com/Rain-kl/Wavelet/internal/model" "github.com/Rain-kl/Wavelet/internal/testhelper" - "github.com/Rain-kl/Wavelet/internal/util" "github.com/gin-gonic/gin" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") func TestGetPublicConfigUsesVisibility(t *testing.T) { dbConn, _, cleanup := testhelper.SetupTestEnvironment(t) @@ -47,7 +46,7 @@ func TestGetPublicConfigUsesVisibility(t *testing.T) { t.Fatalf("GetPublicConfig() status = %d, want %d; body = %s", w.Code, http.StatusOK, w.Body.String()) } - var resp util.ResponseAny + var resp response.Any if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil { t.Fatalf("json.Unmarshal(GetPublicConfig()) error = %v", err) } diff --git a/internal/apps/custom/routers.go b/internal/apps/custom/routers.go index b7cc4de7..32648f04 100644 --- a/internal/apps/custom/routers.go +++ b/internal/apps/custom/routers.go @@ -4,20 +4,19 @@ // Package custom provides custom business handlers package custom -import ( - "net/http" +import ("net/http" - "github.com/Rain-kl/Wavelet/internal/util" "github.com/gin-gonic/gin" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") // Hello is a sample handler for custom business logic // @Summary Sample Hello API // @Description A sample business API for customization // @Tags custom // @Produce json -// @Success 200 {object} util.ResponseAny{data=string} "成功" +// @Success 200 {object} response.Any{data=string} "成功" // @Router /api/v1/custom/hello [get] func Hello(c *gin.Context) { - c.JSON(http.StatusOK, util.OK("Hello from custom business module!")) + c.JSON(http.StatusOK, response.OK("Hello from custom business module!")) } diff --git a/internal/apps/health/routers.go b/internal/apps/health/routers.go index e78cbc3f..e9733836 100644 --- a/internal/apps/health/routers.go +++ b/internal/apps/health/routers.go @@ -5,20 +5,19 @@ // Package health 提供健康检查端点 package health -import ( - "net/http" +import ("net/http" - "github.com/Rain-kl/Wavelet/internal/util" "github.com/gin-gonic/gin" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") // Health 健康检查 // @Summary 健康检查 // @Description 检查服务是否正常运行,可用于负载均衡存活探测 // @Tags health // @Produce json -// @Success 200 {object} util.ResponseAny{data=string} "服务正常" +// @Success 200 {object} response.Any{data=string} "服务正常" // @Router /api/health [get] func Health(c *gin.Context) { - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } diff --git a/internal/apps/oauth/oauth_test.go b/internal/apps/oauth/oauth_test.go index 643692f3..5e2a9468 100644 --- a/internal/apps/oauth/oauth_test.go +++ b/internal/apps/oauth/oauth_test.go @@ -340,7 +340,7 @@ func setupTestRouter(dbConn *gorm.DB, mockRedis *mockRedisClient, mockClient *ht r.Use(mockContextMiddleware(mockClient)) store := cookie.NewStore([]byte(config.Config.App.SessionSecret)) - store.Options(util.GetSessionOptions(3600)) + store.Options(GetSessionOptions(3600)) r.Use(sessions.Sessions(config.Config.App.SessionCookieName, store)) db.SetDB(dbConn) diff --git a/internal/apps/oauth/routers.go b/internal/apps/oauth/routers.go index 1de779cd..e5be215a 100644 --- a/internal/apps/oauth/routers.go +++ b/internal/apps/oauth/routers.go @@ -4,15 +4,15 @@ package oauth -import ( - "net/http" +import ("net/http" "github.com/Rain-kl/Wavelet/internal/model" - "github.com/Rain-kl/Wavelet/internal/util" "github.com/Rain-kl/Wavelet/pkg/logger" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" -) + "github.com/Rain-kl/Wavelet/internal/util" + + "github.com/Rain-kl/Wavelet/internal/common/response") // BasicUserInfo 用户基本信息结构体 type BasicUserInfo struct { @@ -54,8 +54,8 @@ func BuildBasicUserInfo(user *model.User, needChange bool) BasicUserInfo { // @Tags oauth // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=oauth.BasicUserInfo} "用户信息" -// @Failure 401 {object} util.ResponseAny "未登录" +// @Success 200 {object} response.Any{data=oauth.BasicUserInfo} "用户信息" +// @Failure 401 {object} response.Any "未登录" // @Router /api/v1/oauth/user-info [get] // @Router /api/v1/user-info [get] // @Router /api/v1/user/self [get] @@ -66,7 +66,7 @@ func UserInfo(c *gin.Context) { c.JSON( http.StatusOK, - util.OK(BuildBasicUserInfo(user, needChange)), + response.OK(BuildBasicUserInfo(user, needChange)), ) } @@ -75,8 +75,8 @@ func UserInfo(c *gin.Context) { // @Description 生成 OAuth 登录 URL,前端跳转至该地址完成授权。返回的 URL 中包含 state 参数用于 CSRF 防护。 // @Tags oauth // @Produce json -// @Success 200 {object} util.ResponseAny{data=string} "OAuth 登录 URL" -// @Failure 500 {object} util.ResponseAny "Redis 异常或内部错误" +// @Success 200 {object} response.Any{data=string} "OAuth 登录 URL" +// @Failure 500 {object} response.Any "Redis 异常或内部错误" // @Router /api/v1/oauth/login [get] // Logout 退出登录 @@ -85,8 +85,8 @@ func UserInfo(c *gin.Context) { // @Tags oauth // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=string} "退出成功" -// @Failure 500 {object} util.ResponseAny "Session 清除失败" +// @Success 200 {object} response.Any{data=string} "退出成功" +// @Failure 500 {object} response.Any "Session 清除失败" // @Router /api/v1/oauth/logout [get] func Logout(c *gin.Context) { session := sessions.Default(c) @@ -95,11 +95,11 @@ func Logout(c *gin.Context) { if userID != nil { logger.InfoF(c.Request.Context(), "[LoginAudit] user logged out: %v, ID: %v, IP: %s", username, userID, c.ClientIP()) } - session.Options(util.GetSessionOptions(-1)) + session.Options(GetSessionOptions(-1)) session.Clear() if err := session.Save(); err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } diff --git a/internal/util/session.go b/internal/apps/oauth/session.go similarity index 94% rename from internal/util/session.go rename to internal/apps/oauth/session.go index 28b0c6c9..fe653b42 100644 --- a/internal/util/session.go +++ b/internal/apps/oauth/session.go @@ -1,8 +1,8 @@ -// Copyright 2025 linux.do // Copyright 2026 Arctel.net // SPDX-License-Identifier: Apache-2.0 -package util +// Package oauth provides authentication and OAuth integration. +package oauth import ( "net/http" diff --git a/internal/apps/oauth/sources.go b/internal/apps/oauth/sources.go index 2f77c504..3eef901e 100644 --- a/internal/apps/oauth/sources.go +++ b/internal/apps/oauth/sources.go @@ -3,8 +3,7 @@ package oauth -import ( - "context" +import ("context" "crypto/sha256" "encoding/hex" "errors" @@ -19,7 +18,6 @@ import ( "github.com/Rain-kl/Wavelet/internal/config" "github.com/Rain-kl/Wavelet/internal/db" "github.com/Rain-kl/Wavelet/internal/model" - "github.com/Rain-kl/Wavelet/internal/util" "github.com/Rain-kl/Wavelet/pkg/logger" "github.com/coreos/go-oidc/v3/oidc" "github.com/gin-contrib/sessions" @@ -27,6 +25,7 @@ import ( "github.com/google/uuid" "golang.org/x/oauth2" "gorm.io/gorm" + "github.com/Rain-kl/Wavelet/internal/common/response" ) // AuthSourceView 登录源展示信息 @@ -215,14 +214,14 @@ func setLoginSession(ctx context.Context, c *gin.Context, user *model.User) erro isSessionCookie = true } } - session.Options(util.GetSessionOptions(maxAge)) + session.Options(GetSessionOptions(maxAge)) if err := session.Save(); err != nil { return err } if isSessionCookie { - util.StripCookieMaxAgeAndExpires(c.Writer.Header(), config.Config.App.SessionCookieName) + StripCookieMaxAgeAndExpires(c.Writer.Header(), config.Config.App.SessionCookieName) } return nil @@ -358,10 +357,10 @@ func buildCallbackResult(user *model.User, status string) OAuthCallbackResult { // @Description 返回当前系统已启用的所有 OAuth 登录源,前端展示登录按钮列表时调用 // @Tags oauth // @Produce json -// @Success 200 {object} util.ResponseAny{data=[]oauth.AuthSourceView} "登录源列表" +// @Success 200 {object} response.Any{data=[]oauth.AuthSourceView} "登录源列表" // @Router /api/v1/oauth/sources [get] func GetLoginSources(c *gin.Context) { - c.JSON(http.StatusOK, util.OK(activeLoginSources(c.Request.Context()))) + c.JSON(http.StatusOK, response.OK(activeLoginSources(c.Request.Context()))) } // GetLoginURL 获取登录授权地址 @@ -370,25 +369,25 @@ func GetLoginSources(c *gin.Context) { // @Tags oauth // @Produce json // @Param source query string false "认证源名称,为空使用第一个启用的认证源" -// @Success 200 {object} util.ResponseAny{data=oauth.OAuthAuthorizeResponse} "授权 URL" -// @Failure 400 {object} util.ResponseAny "认证源不存在或未配置" -// @Failure 500 {object} util.ResponseAny "Redis 异常 or 构造 URL 失败" +// @Success 200 {object} response.Any{data=oauth.OAuthAuthorizeResponse} "授权 URL" +// @Failure 400 {object} response.Any "认证源不存在或未配置" +// @Failure 500 {object} response.Any "Redis 异常 or 构造 URL 失败" // @Router /api/v1/oauth/login [get] func GetLoginURL(c *gin.Context) { ctx := c.Request.Context() if !isOIDCLoginEnabled(ctx) { - c.JSON(http.StatusBadRequest, util.Err(errAuthSourceDisabled)) + c.JSON(http.StatusBadRequest, response.Err(errAuthSourceDisabled)) return } source, err := resolveAuthSource(ctx, c.Query("source")) if err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } if !source.IsActive { - c.JSON(http.StatusBadRequest, util.Err(errAuthSourceDisabled)) + c.JSON(http.StatusBadRequest, response.Err(errAuthSourceDisabled)) return } @@ -396,7 +395,7 @@ func GetLoginURL(c *gin.Context) { token, isNew := ensureSessionToken(session) if isNew { if err := session.Save(); err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } } @@ -412,20 +411,20 @@ func GetLoginURL(c *gin.Context) { SessionHash: sessionHash, }) if err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } if err := db.Redis.Set(c.Request.Context(), db.PrefixedKey(fmt.Sprintf(OAuthStateCacheKeyFormat, state)), payloadValue, OAuthStateCacheKeyExpiration).Err(); err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } authorizeURL, err := buildAuthorizeURL(c.Request.Context(), source, state) if err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(OAuthAuthorizeResponse{AuthorizeURL: authorizeURL})) + c.JSON(http.StatusOK, response.OK(OAuthAuthorizeResponse{AuthorizeURL: authorizeURL})) } func buildAuthorizeURL(ctx context.Context, source *model.AuthSource, state string) (string, error) { @@ -450,25 +449,25 @@ func buildAuthorizeURL(ctx context.Context, source *model.AuthSource, state stri // @Produce json // @Param source path string true "认证源名称" // @Param purpose query string false "授权目的:login(登录)或 bind(绑定账号),默认 login" -// @Success 200 {object} util.ResponseAny{data=oauth.OAuthAuthorizeResponse} "授权 URL" -// @Failure 400 {object} util.ResponseAny "认证源不存在或未启用" -// @Failure 500 {object} util.ResponseAny "Redis 异常或构造 URL 失败" +// @Success 200 {object} response.Any{data=oauth.OAuthAuthorizeResponse} "授权 URL" +// @Failure 400 {object} response.Any "认证源不存在或未启用" +// @Failure 500 {object} response.Any "Redis 异常或构造 URL 失败" // @Router /api/v1/oauth/{source}/authorize [get] func Authorize(c *gin.Context) { ctx := c.Request.Context() if !isOIDCLoginEnabled(ctx) { - c.JSON(http.StatusBadRequest, util.Err(errAuthSourceDisabled)) + c.JSON(http.StatusBadRequest, response.Err(errAuthSourceDisabled)) return } source, err := resolveAuthSource(ctx, c.Param("source")) if err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } if !source.IsActive { - c.JSON(http.StatusBadRequest, util.Err(errAuthSourceDisabled)) + c.JSON(http.StatusBadRequest, response.Err(errAuthSourceDisabled)) return } purpose := strings.ToLower(strings.TrimSpace(c.Query("purpose"))) @@ -479,14 +478,14 @@ func Authorize(c *gin.Context) { session := sessions.Default(c) userID := GetUserIDFromSession(session) if purpose == OAuthPurposeBind && userID == 0 { - c.JSON(http.StatusUnauthorized, util.Err(common.UnAuthorized)) + c.JSON(http.StatusUnauthorized, response.Err(common.UnAuthorized)) return } token, isNew := ensureSessionToken(session) if isNew { if err := session.Save(); err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } } @@ -501,20 +500,20 @@ func Authorize(c *gin.Context) { SessionHash: sessionHash, }) if err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } if err := db.Redis.Set(c.Request.Context(), db.PrefixedKey(fmt.Sprintf(OAuthStateCacheKeyFormat, state)), payloadValue, OAuthStateCacheKeyExpiration).Err(); err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } authorizeURL, err := buildAuthorizeURL(c.Request.Context(), source, state) if err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(OAuthAuthorizeResponse{AuthorizeURL: authorizeURL})) + c.JSON(http.StatusOK, response.OK(OAuthAuthorizeResponse{AuthorizeURL: authorizeURL})) } // Callback OAuth 回调处理 @@ -524,15 +523,15 @@ func Authorize(c *gin.Context) { // @Accept json // @Produce json // @Param request body oauth.CallbackRequest true "回调请求参数" -// @Success 200 {object} util.ResponseAny{data=oauth.OAuthCallbackResult} "登录或绑定成功" -// @Failure 400 {object} util.ResponseAny "state 无效、参数错误或认证源错误" -// @Failure 401 {object} util.ResponseAny "绑定场景未登录" -// @Failure 500 {object} util.ResponseAny "OAuth 认证失败或内部错误" +// @Success 200 {object} response.Any{data=oauth.OAuthCallbackResult} "登录或绑定成功" +// @Failure 400 {object} response.Any "state 无效、参数错误或认证源错误" +// @Failure 401 {object} response.Any "绑定场景未登录" +// @Failure 500 {object} response.Any "OAuth 认证失败或内部错误" // @Router /api/v1/oauth/callback [post] func Callback(c *gin.Context) { var req CallbackRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -540,14 +539,14 @@ func Callback(c *gin.Context) { stateKey := db.PrefixedKey(fmt.Sprintf(OAuthStateCacheKeyFormat, req.State)) payloadRaw, err := db.Redis.Get(ctx, stateKey).Result() if err != nil { - c.JSON(http.StatusBadRequest, util.Err(errInvalidState)) + c.JSON(http.StatusBadRequest, response.Err(errInvalidState)) return } _ = db.Redis.Del(ctx, stateKey) payload, err := decodeOAuthStatePayload(payloadRaw) if err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -555,55 +554,55 @@ func Callback(c *gin.Context) { currentUserID := GetUserIDFromSession(session) if payload.Purpose == OAuthPurposeBind && currentUserID == 0 { - c.JSON(http.StatusUnauthorized, util.Err(common.UnAuthorized)) + c.JSON(http.StatusUnauthorized, response.Err(common.UnAuthorized)) return } token, ok := session.Get(SessionTokenKey).(string) if !ok || token == "" { - c.JSON(http.StatusBadRequest, util.Err("invalid session context")) + c.JSON(http.StatusBadRequest, response.Err("invalid session context")) return } if hashSessionToken(token) != payload.SessionHash { - c.JSON(http.StatusBadRequest, util.Err("session mismatch for oauth state")) + c.JSON(http.StatusBadRequest, response.Err("session mismatch for oauth state")) return } if payload.Purpose == OAuthPurposeBind && currentUserID != payload.UserID { - c.JSON(http.StatusBadRequest, util.Err("user context mismatch for oauth binding")) + c.JSON(http.StatusBadRequest, response.Err("user context mismatch for oauth binding")) return } if !isOIDCLoginEnabled(ctx) { - c.JSON(http.StatusBadRequest, util.Err(errAuthSourceDisabled)) + c.JSON(http.StatusBadRequest, response.Err(errAuthSourceDisabled)) return } source, err := resolveAuthSource(ctx, payload.SourceName) if err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } if !source.IsActive { - c.JSON(http.StatusBadRequest, util.Err(errAuthSourceDisabled)) + c.JSON(http.StatusBadRequest, response.Err(errAuthSourceDisabled)) return } redirectURL, err := getFrontendLoginRedirectURL(ctx) if err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } userInfo, err := buildOAuthUserInfo(ctx, source, req.Code, req.State, redirectURL) if err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } if err := normalizeOAuthUserInfo(userInfo); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } if userInfo.Sub == "" { @@ -622,12 +621,12 @@ func Callback(c *gin.Context) { func handleCallbackBind(ctx context.Context, c *gin.Context, source *model.AuthSource, userInfo *model.OAuthUserInfo) { userID := GetUserIDFromContext(c) if userID == 0 { - c.JSON(http.StatusUnauthorized, util.Err(common.UnAuthorized)) + c.JSON(http.StatusUnauthorized, response.Err(common.UnAuthorized)) return } var user model.User if err := db.DB(ctx).First(&user, "id = ?", userID).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } if err := model.BindExternalAccount(ctx, &model.ExternalAccount{ @@ -637,12 +636,12 @@ func handleCallbackBind(ctx context.Context, c *gin.Context, source *model.AuthS ExternalUsername: userInfo.Username, Email: userInfo.Email, }); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } user.LastLoginAt = time.Now() _ = db.DB(ctx).Model(&user).Update("last_login_at", user.LastLoginAt).Error - c.JSON(http.StatusOK, util.OK(buildCallbackResult(&user, "bound"))) + c.JSON(http.StatusOK, response.OK(buildCallbackResult(&user, "bound"))) } // handleCallbackLogin 处理 OAuth 回调中的登录流程(查找已有帐号或自动注册) @@ -653,7 +652,7 @@ func handleCallbackLogin(ctx context.Context, c *gin.Context, source *model.Auth switch { case err == nil: if err := db.DB(ctx).First(&user, "id = ?", account.UserID).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } case errors.Is(err, gorm.ErrRecordNotFound): @@ -663,14 +662,14 @@ func handleCallbackLogin(ctx context.Context, c *gin.Context, source *model.Auth } user = newUser default: - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } user.LastLoginAt = time.Now() _ = db.DB(ctx).Model(&user).Update("last_login_at", user.LastLoginAt).Error if err := setLoginSession(ctx, c, &user); err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } @@ -678,7 +677,7 @@ func handleCallbackLogin(ctx context.Context, c *gin.Context, source *model.Auth custom_events.TriggerAdminLoginEvent(ctx, &user, c.ClientIP()) - c.JSON(http.StatusOK, util.OK(buildCallbackResult(&user, "logged_in"))) + c.JSON(http.StatusOK, response.OK(buildCallbackResult(&user, "logged_in"))) } // handleCallbackRegister 处理 OAuth 回调中的自动注册流程 @@ -690,20 +689,20 @@ func handleCallbackRegister(ctx context.Context, c *gin.Context, source *model.A } if !registrationEnabled { - c.JSON(http.StatusOK, util.OK(buildCallbackResult(nil, "need_bind"))) + c.JSON(http.StatusOK, response.OK(buildCallbackResult(nil, "need_bind"))) return model.User{}, false } username, uniqueErr := uniqueUsername(ctx, userInfo.Username) if uniqueErr != nil { - c.JSON(http.StatusInternalServerError, util.Err(uniqueErr.Error())) + c.JSON(http.StatusInternalServerError, response.Err(uniqueErr.Error())) return model.User{}, false } userInfo.Username = username var user model.User if err := user.CreateUser(ctx, db.DB(ctx), userInfo); err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return model.User{}, false } if err := model.BindExternalAccount(ctx, &model.ExternalAccount{ @@ -713,7 +712,7 @@ func handleCallbackRegister(ctx context.Context, c *gin.Context, source *model.A ExternalUsername: userInfo.Username, Email: userInfo.Email, }); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return model.User{}, false } logger.InfoF(ctx, "[LoginAudit] successful OAuth registration via source: %s, external ID: %s, user: %s, ID: %d, IP: %s", source.Name, userInfo.Sub, user.Username, user.ID, c.ClientIP()) @@ -727,18 +726,18 @@ func handleCallbackRegister(ctx context.Context, c *gin.Context, source *model.A // @Tags oauth // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=[]model.ExternalAccountView} "外部帐号列表" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=[]model.ExternalAccountView} "外部帐号列表" +// @Failure 401 {object} response.Any "未登录" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/oauth/external-accounts [get] func ListExternalAccounts(c *gin.Context) { userID := GetUserIDFromContext(c) accounts, err := model.ListExternalAccountsByUserID(c.Request.Context(), userID) if err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(accounts)) + c.JSON(http.StatusOK, response.OK(accounts)) } // DeleteExternalAccount 解除外部帐号绑定 @@ -748,25 +747,25 @@ func ListExternalAccounts(c *gin.Context) { // @Produce json // @Security SessionCookie // @Param id path uint64 true "外部帐号绑定记录 ID" -// @Success 200 {object} util.ResponseAny{data=string} "解除绑定成功" -// @Failure 400 {object} util.ResponseAny "ID 无效或解除失败" -// @Failure 401 {object} util.ResponseAny "未登录" +// @Success 200 {object} response.Any{data=string} "解除绑定成功" +// @Failure 400 {object} response.Any "ID 无效或解除失败" +// @Failure 401 {object} response.Any "未登录" // @Router /api/v1/oauth/external-accounts/{id}/delete [post] func DeleteExternalAccount(c *gin.Context) { userID := GetUserIDFromContext(c) if userID == 0 { - c.JSON(http.StatusUnauthorized, util.Err(common.UnAuthorized)) + c.JSON(http.StatusUnauthorized, response.Err(common.UnAuthorized)) return } rawID := strings.TrimSpace(c.Param("id")) id, err := strconv.ParseUint(rawID, 10, 64) if err != nil || id == 0 { - c.JSON(http.StatusBadRequest, util.Err(errInvalidExternalAccountBindingID)) + c.JSON(http.StatusBadRequest, response.Err(errInvalidExternalAccountBindingID)) return } if err := model.DeleteExternalAccountForUser(c.Request.Context(), id, userID); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } diff --git a/internal/apps/risk_control/middleware.go b/internal/apps/risk_control/middleware.go index 1cf885d1..de13775d 100644 --- a/internal/apps/risk_control/middleware.go +++ b/internal/apps/risk_control/middleware.go @@ -4,8 +4,7 @@ // Package risk_control 提供风险控制中间件 package risk_control -import ( - "encoding/json" +import ("encoding/json" "net/http" "time" @@ -15,7 +14,8 @@ import ( "github.com/Rain-kl/Wavelet/internal/model" "github.com/Rain-kl/Wavelet/internal/util" "github.com/gin-gonic/gin" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") // RiskControlMiddleware 全局日志采集中间件 func RiskControlMiddleware() gin.HandlerFunc { @@ -28,7 +28,7 @@ func RiskControlMiddleware() gin.HandlerFunc { // 1. 限流背压检测(检测本地缓冲队列是否已满) if IsBufferFull() { - c.AbortWithStatusJSON(http.StatusTooManyRequests, util.Err("系统繁忙,请稍后再试")) + c.AbortWithStatusJSON(http.StatusTooManyRequests, response.Err("系统繁忙,请稍后再试")) return } diff --git a/internal/apps/upload/file_management.go b/internal/apps/upload/file_management.go index 18cdf4b8..c02dfe82 100644 --- a/internal/apps/upload/file_management.go +++ b/internal/apps/upload/file_management.go @@ -11,6 +11,7 @@ import ( "strings" "github.com/Rain-kl/Wavelet/internal/apps/oauth" + "github.com/Rain-kl/Wavelet/internal/common/response" "github.com/Rain-kl/Wavelet/internal/db" "github.com/Rain-kl/Wavelet/internal/model" "github.com/Rain-kl/Wavelet/internal/util" @@ -46,16 +47,16 @@ type listFilesResponse struct { // @Param extension query string false "扩展名过滤" // @Param user_id query uint64 false "上传用户 ID" // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=listFilesResponse} "查询成功" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" +// @Success 200 {object} response.Any{data=listFilesResponse} "查询成功" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" // @Router /api/v1/admin/uploads [get] func ListFiles(c *gin.Context) { ctx := c.Request.Context() var req listFilesRequest if err := c.ShouldBindQuery(&req); err != nil { - c.JSON(http.StatusOK, util.Err(ErrInvalidParams)) + c.JSON(http.StatusOK, response.Err(ErrInvalidParams)) return } if req.Page <= 0 { @@ -83,18 +84,18 @@ func ListFiles(c *gin.Context) { var total int64 if err := query.Count(&total).Error; err != nil { - c.JSON(http.StatusOK, util.Err(ErrQueryFileCountFailed)) + c.JSON(http.StatusOK, response.Err(ErrQueryFileCountFailed)) return } var items []model.Upload offset := (req.Page - 1) * req.PageSize if err := query.Order("created_at DESC").Offset(offset).Limit(req.PageSize).Find(&items).Error; err != nil { - c.JSON(http.StatusOK, util.Err(ErrQueryFileListFailed)) + c.JSON(http.StatusOK, response.Err(ErrQueryFileListFailed)) return } - c.JSON(http.StatusOK, util.OK(listFilesResponse{ + c.JSON(http.StatusOK, response.OK(listFilesResponse{ Total: total, Page: req.Page, PageSize: req.PageSize, @@ -109,20 +110,20 @@ func ListFiles(c *gin.Context) { // @Produce json // @Param id path string true "文件 ID" // @Security SessionCookie -// @Success 200 {object} util.ResponseAny "删除成功" -// @Failure 403 {object} util.ResponseAny "无权操作" -// @Failure 404 {object} util.ResponseAny "文件不存在" +// @Success 200 {object} response.Any "删除成功" +// @Failure 403 {object} response.Any "无权操作" +// @Failure 404 {object} response.Any "文件不存在" // @Router /api/v1/admin/uploads/{id} [delete] func DeleteFile(c *gin.Context) { ctx := c.Request.Context() if StorageReadOnly(ctx) { - c.JSON(http.StatusConflict, util.Err(ErrStorageReadOnly)) + c.JSON(http.StatusConflict, response.Err(ErrStorageReadOnly)) return } uploadID, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { - c.JSON(http.StatusOK, util.Err(ErrInvalidFileID)) + c.JSON(http.StatusOK, response.Err(ErrInvalidFileID)) return } @@ -132,14 +133,14 @@ func DeleteFile(c *gin.Context) { c.AbortWithStatus(http.StatusNotFound) return } - c.JSON(http.StatusOK, util.Err(ErrQueryUploadRecordFailed)) + c.JSON(http.StatusOK, response.Err(ErrQueryUploadRecordFailed)) return } if err := db.DB(ctx).Model(&upload).Update("status", model.UploadStatusDeleted).Error; err != nil { - c.JSON(http.StatusOK, util.Err(ErrDeleteFileFailed)) + c.JSON(http.StatusOK, response.Err(ErrDeleteFileFailed)) return } - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } // GetDistinctUploadTypes 获取数据库中所有已存在的文件业务类型 @@ -148,10 +149,10 @@ func DeleteFile(c *gin.Context) { // @Tags admin // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=[]string} "业务类型列表" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=[]string} "业务类型列表" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/uploads/types [get] func GetDistinctUploadTypes(c *gin.Context) { var dbTypes []string @@ -159,11 +160,11 @@ func GetDistinctUploadTypes(c *gin.Context) { Where("type IS NOT NULL AND type != ''"). Distinct(). Pluck("type", &dbTypes).Error; err != nil { - c.JSON(http.StatusInternalServerError, util.Err(err.Error())) + c.JSON(http.StatusInternalServerError, response.Err(err.Error())) return } sort.Strings(dbTypes) - c.JSON(http.StatusOK, util.OK(dbTypes)) + c.JSON(http.StatusOK, response.OK(dbTypes)) } type listMyFilesRequest struct { @@ -192,8 +193,8 @@ type listMyFilesResponse struct { // @Param type query string false "业务分类过滤" // @Param extension query string false "扩展名过滤" // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=listMyFilesResponse} "查询成功" -// @Failure 401 {object} util.ResponseAny "未登录" +// @Success 200 {object} response.Any{data=listMyFilesResponse} "查询成功" +// @Failure 401 {object} response.Any "未登录" // @Router /api/v1/upload/my [get] func ListMyFiles(c *gin.Context) { currUser, _ := util.GetFromContext[*model.User](c, oauth.UserObjKey) @@ -201,7 +202,7 @@ func ListMyFiles(c *gin.Context) { var req listMyFilesRequest if err := c.ShouldBindQuery(&req); err != nil { - c.JSON(http.StatusOK, util.Err(ErrInvalidParams)) + c.JSON(http.StatusOK, response.Err(ErrInvalidParams)) return } if req.Page <= 0 { @@ -226,18 +227,18 @@ func ListMyFiles(c *gin.Context) { var total int64 if err := query.Count(&total).Error; err != nil { - c.JSON(http.StatusOK, util.Err(ErrQueryFileCountFailed)) + c.JSON(http.StatusOK, response.Err(ErrQueryFileCountFailed)) return } var items []model.Upload offset := (req.Page - 1) * req.PageSize if err := query.Order("created_at DESC").Offset(offset).Limit(req.PageSize).Find(&items).Error; err != nil { - c.JSON(http.StatusOK, util.Err(ErrQueryFileListFailed)) + c.JSON(http.StatusOK, response.Err(ErrQueryFileListFailed)) return } - c.JSON(http.StatusOK, util.OK(listMyFilesResponse{ + c.JSON(http.StatusOK, response.OK(listMyFilesResponse{ Total: total, Page: req.Page, PageSize: req.PageSize, @@ -252,21 +253,21 @@ func ListMyFiles(c *gin.Context) { // @Produce json // @Param id path string true "文件 ID" // @Security SessionCookie -// @Success 200 {object} util.ResponseAny "删除成功" -// @Failure 403 {object} util.ResponseAny "无权操作" -// @Failure 404 {object} util.ResponseAny "文件不存在" +// @Success 200 {object} response.Any "删除成功" +// @Failure 403 {object} response.Any "无权操作" +// @Failure 404 {object} response.Any "文件不存在" // @Router /api/v1/upload/{id} [delete] func DeleteMyFile(c *gin.Context) { currUser, _ := util.GetFromContext[*model.User](c, oauth.UserObjKey) ctx := c.Request.Context() if StorageReadOnly(ctx) { - c.JSON(http.StatusConflict, util.Err(ErrStorageReadOnly)) + c.JSON(http.StatusConflict, response.Err(ErrStorageReadOnly)) return } uploadID, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { - c.JSON(http.StatusOK, util.Err(ErrInvalidFileID)) + c.JSON(http.StatusOK, response.Err(ErrInvalidFileID)) return } @@ -276,7 +277,7 @@ func DeleteMyFile(c *gin.Context) { c.AbortWithStatus(http.StatusNotFound) return } - c.JSON(http.StatusOK, util.Err(ErrQueryUploadRecordFailed)) + c.JSON(http.StatusOK, response.Err(ErrQueryUploadRecordFailed)) return } @@ -286,10 +287,10 @@ func DeleteMyFile(c *gin.Context) { } if err := db.DB(ctx).Model(&upload).Update("status", model.UploadStatusDeleted).Error; err != nil { - c.JSON(http.StatusOK, util.Err(ErrDeleteFileFailed)) + c.JSON(http.StatusOK, response.Err(ErrDeleteFileFailed)) return } - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } type updateMyFileRequest struct { @@ -306,27 +307,27 @@ type updateMyFileRequest struct { // @Param id path string true "文件 ID" // @Param request body updateMyFileRequest true "更新字段" // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=model.Upload} "更新成功" -// @Failure 403 {object} util.ResponseAny "无权操作" -// @Failure 404 {object} util.ResponseAny "文件不存在" +// @Success 200 {object} response.Any{data=model.Upload} "更新成功" +// @Failure 403 {object} response.Any "无权操作" +// @Failure 404 {object} response.Any "文件不存在" // @Router /api/v1/upload/{id} [put] func UpdateMyFile(c *gin.Context) { currUser, _ := util.GetFromContext[*model.User](c, oauth.UserObjKey) ctx := c.Request.Context() if StorageReadOnly(ctx) { - c.JSON(http.StatusConflict, util.Err(ErrStorageReadOnly)) + c.JSON(http.StatusConflict, response.Err(ErrStorageReadOnly)) return } uploadID, err := strconv.ParseUint(c.Param("id"), 10, 64) if err != nil { - c.JSON(http.StatusOK, util.Err(ErrInvalidFileID)) + c.JSON(http.StatusOK, response.Err(ErrInvalidFileID)) return } var req updateMyFileRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, util.Err(ErrInvalidParams)) + c.JSON(http.StatusOK, response.Err(ErrInvalidParams)) return } @@ -336,7 +337,7 @@ func UpdateMyFile(c *gin.Context) { c.AbortWithStatus(http.StatusNotFound) return } - c.JSON(http.StatusOK, util.Err(ErrQueryUploadRecordFailed)) + c.JSON(http.StatusOK, response.Err(ErrQueryUploadRecordFailed)) return } @@ -355,10 +356,10 @@ func UpdateMyFile(c *gin.Context) { if len(updates) > 0 { if err := db.DB(ctx).Model(&upload).Updates(updates).Error; err != nil { - c.JSON(http.StatusOK, util.Err("更新文件记录失败")) + c.JSON(http.StatusOK, response.Err("更新文件记录失败")) return } } - c.JSON(http.StatusOK, util.OK(upload)) + c.JSON(http.StatusOK, response.OK(upload)) } diff --git a/internal/apps/upload/file_server.go b/internal/apps/upload/file_server.go index 639573fe..926b5352 100644 --- a/internal/apps/upload/file_server.go +++ b/internal/apps/upload/file_server.go @@ -4,8 +4,7 @@ package upload -import ( - "bytes" +import ("bytes" "context" "encoding/json" "errors" @@ -34,10 +33,10 @@ import ( // @Param id path string true "文件 ID" // @Param quality query string false "图片质量 (low, medium, high, origin),默认为 origin" // @Success 200 {file} file "成功获取文件内容" -// @Failure 400 {object} util.ResponseAny "文件 ID 格式错误" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 404 {object} util.ResponseAny "文件未找到" -// @Failure 500 {object} util.ResponseAny "服务内部错误" +// @Failure 400 {object} response.Any "文件 ID 格式错误" +// @Failure 401 {object} response.Any "未登录" +// @Failure 404 {object} response.Any "文件未找到" +// @Failure 500 {object} response.Any "服务内部错误" // @Router /f/{id} [get] func ServeFileByID(c *gin.Context) { upload, err := getUploadRecordByID(c) diff --git a/internal/apps/upload/routers.go b/internal/apps/upload/routers.go index c0191bb3..639f4930 100644 --- a/internal/apps/upload/routers.go +++ b/internal/apps/upload/routers.go @@ -4,8 +4,7 @@ package upload -import ( - "archive/zip" +import ("archive/zip" "bytes" "context" "crypto/sha256" @@ -32,6 +31,7 @@ import ( "github.com/Rain-kl/Wavelet/pkg/logger" "github.com/gin-gonic/gin" "gorm.io/gorm" + "github.com/Rain-kl/Wavelet/internal/common/response" ) type batchDownloadRequest struct { @@ -48,10 +48,10 @@ type batchDownloadRequest struct { // @Param type formData string false "业务分类 (例如: avatar, attachment, doc,默认为 generic)" // @Param metadata formData string false "额外的 JSON 格式元数据" // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=model.Upload} "上传成功" -// @Failure 400 {object} util.ResponseAny "请求参数错误或文件受限" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=model.Upload} "上传成功" +// @Failure 400 {object} response.Any "请求参数错误或文件受限" +// @Failure 401 {object} response.Any "未登录" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/upload [post] // //nolint:revive @@ -67,20 +67,20 @@ func UploadFile(c *gin.Context) { header, err := c.FormFile("file") if err != nil { - c.JSON(http.StatusOK, util.Err(ErrNoFileSelected)) + c.JSON(http.StatusOK, response.Err(ErrNoFileSelected)) return } file, err := header.Open() if err != nil { - c.JSON(http.StatusOK, util.Err(ErrOpenFileFailed)) + c.JSON(http.StatusOK, response.Err(ErrOpenFileFailed)) return } defer func() { _ = file.Close() }() // 校验大小 if header.Size > maxUploadSize { - c.JSON(http.StatusOK, util.Err(ErrGenericFileTooLarge)) + c.JSON(http.StatusOK, response.Err(ErrGenericFileTooLarge)) return } @@ -93,7 +93,7 @@ func UploadFile(c *gin.Context) { // 3. 校验文件后缀是否在允许的系统配置列表中 if errMsg := validateUploadExtension(ctx, ext); errMsg != "" { - c.JSON(http.StatusOK, util.Err(errMsg)) + c.JSON(http.StatusOK, response.Err(errMsg)) return } @@ -102,7 +102,7 @@ func UploadFile(c *gin.Context) { var buf bytes.Buffer size, err := io.Copy(&buf, io.TeeReader(file, hashWriter)) if err != nil { - c.JSON(http.StatusOK, util.Err(ErrProcessFileFailed)) + c.JSON(http.StatusOK, response.Err(ErrProcessFileFailed)) return } @@ -111,7 +111,7 @@ func UploadFile(c *gin.Context) { // 校验真实 MIME Type 是否与常见图片扩展名匹配,防止 Polyglot / HTML 注入攻击 if isImageExtension(ext) && !strings.HasPrefix(mimeType, "image/") { - c.JSON(http.StatusOK, util.Err(ErrFileContentExtensionMismatch)) + c.JSON(http.StatusOK, response.Err(ErrFileContentExtensionMismatch)) return } @@ -129,7 +129,7 @@ func UploadFile(c *gin.Context) { var err error accessMode, err = strconv.Atoi(accessModeStr) if err != nil || (accessMode != 0 && accessMode != 1) { - c.JSON(http.StatusOK, util.Err("无效的 access_mode 参数")) + c.JSON(http.StatusOK, response.Err("无效的 access_mode 参数")) return } } @@ -140,14 +140,14 @@ func UploadFile(c *gin.Context) { return } if lookupErr != nil && !errors.Is(lookupErr, gorm.ErrRecordNotFound) { - c.JSON(http.StatusOK, util.Err(ErrFileValidationFailed)) + c.JSON(http.StatusOK, response.Err(ErrFileValidationFailed)) return } // 7. 解析可选元数据字段 meta, errMsg := parseUploadMetadata(c, mimeType) if errMsg != "" { - c.JSON(http.StatusOK, util.Err(errMsg)) + c.JSON(http.StatusOK, response.Err(errMsg)) return } @@ -157,7 +157,7 @@ func UploadFile(c *gin.Context) { // 8. 写入当前活动存储驱动。 storageDriver, subPath, errMsg := storeUploadFile(ctx, subPath, size, mimeType, &buf, &meta) if errMsg != "" { - c.JSON(http.StatusOK, util.Err(errMsg)) + c.JSON(http.StatusOK, response.Err(errMsg)) return } @@ -179,11 +179,11 @@ func UploadFile(c *gin.Context) { } if err := saveUploadRecord(ctx, &newUpload, storageDriver, subPath); err != "" { - c.JSON(http.StatusOK, util.Err(err)) + c.JSON(http.StatusOK, response.Err(err)) return } - c.JSON(http.StatusOK, util.OK(newUpload)) + c.JSON(http.StatusOK, response.OK(newUpload)) } // DownloadFile 通用单文件下载接口 @@ -195,9 +195,9 @@ func UploadFile(c *gin.Context) { // @Param quality query string false "图片质量 (low, medium, high, origin),默认为 origin" // @Security SessionCookie // @Success 200 {file} file "成功下载文件" -// @Failure 400 {object} util.ResponseAny "参数错误" -// @Failure 404 {object} util.ResponseAny "文件不存在" -// @Failure 500 {object} util.ResponseAny "服务内部错误" +// @Failure 400 {object} response.Any "参数错误" +// @Failure 404 {object} response.Any "文件不存在" +// @Failure 500 {object} response.Any "服务内部错误" // @Router /api/v1/admin/uploads/download/{id} [get] func DownloadFile(c *gin.Context) { upload, err := getUploadRecordByID(c) @@ -207,10 +207,10 @@ func DownloadFile(c *gin.Context) { return } if _, ok := err.(*strconv.NumError); ok { - c.JSON(http.StatusOK, util.Err(ErrInvalidFileID)) + c.JSON(http.StatusOK, response.Err(ErrInvalidFileID)) return } - c.JSON(http.StatusOK, util.Err(ErrQueryUploadRecordFailed)) + c.JSON(http.StatusOK, response.Err(ErrQueryUploadRecordFailed)) return } @@ -247,15 +247,15 @@ func DownloadFile(c *gin.Context) { // @Param request body upload.batchDownloadRequest true "包含文件 ID 数组 of string 的请求体" // @Security SessionCookie // @Success 200 {file} file "成功下载打包后的 ZIP" -// @Failure 400 {object} util.ResponseAny "参数错误" -// @Failure 500 {object} util.ResponseAny "打包失败" +// @Failure 400 {object} response.Any "参数错误" +// @Failure 500 {object} response.Any "打包失败" // @Router /api/v1/admin/uploads/download/batch [post] func BatchDownloadFiles(c *gin.Context) { ctx := c.Request.Context() var req batchDownloadRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, util.Err(ErrInvalidBatchDownloadRequest)) + c.JSON(http.StatusOK, response.Err(ErrInvalidBatchDownloadRequest)) return } @@ -264,7 +264,7 @@ func BatchDownloadFiles(c *gin.Context) { for _, idStr := range req.IDs { id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { - c.JSON(http.StatusOK, util.Err(fmt.Sprintf(ErrInvalidIDValueFormat, idStr))) + c.JSON(http.StatusOK, response.Err(fmt.Sprintf(ErrInvalidIDValueFormat, idStr))) return } ids = append(ids, id) @@ -273,12 +273,12 @@ func BatchDownloadFiles(c *gin.Context) { // 查库获取所有匹配且正常的文件记录 var uploads []model.Upload if err := db.DB(ctx).Where("id IN ? AND status IN (?, ?)", ids, model.UploadStatusPending, model.UploadStatusUsed).Find(&uploads).Error; err != nil { - c.JSON(http.StatusOK, util.Err(ErrRetrieveUploadRecordsFailed)) + c.JSON(http.StatusOK, response.Err(ErrRetrieveUploadRecordsFailed)) return } if len(uploads) == 0 { - c.JSON(http.StatusOK, util.Err(ErrNoValidFilesForArchive)) + c.JSON(http.StatusOK, response.Err(ErrNoValidFilesForArchive)) return } @@ -363,7 +363,7 @@ func tryInstantUpload(ctx context.Context, c *gin.Context, currUser *model.User, return false, err } if StorageReadOnly(ctx) { - c.JSON(http.StatusConflict, util.Err(ErrStorageReadOnly)) + c.JSON(http.StatusConflict, response.Err(ErrStorageReadOnly)) return true, nil } @@ -385,12 +385,12 @@ func tryInstantUpload(ctx context.Context, c *gin.Context, currUser *model.User, } if err := db.DB(ctx).Create(&newUpload).Error; err != nil { - c.JSON(http.StatusOK, util.Err(ErrSaveUploadRecordFailed)) + c.JSON(http.StatusOK, response.Err(ErrSaveUploadRecordFailed)) return true, err } logger.InfoF(ctx, "文件触发秒传成功! ID: %d, Path: %s", id, existing.FilePath) - c.JSON(http.StatusOK, util.OK(newUpload)) + c.JSON(http.StatusOK, response.OK(newUpload)) return true, nil } diff --git a/internal/apps/upload/stats.go b/internal/apps/upload/stats.go index 531fd979..c5ff062f 100644 --- a/internal/apps/upload/stats.go +++ b/internal/apps/upload/stats.go @@ -3,16 +3,15 @@ package upload -import ( - "net/http" +import ("net/http" "strings" "time" "github.com/Rain-kl/Wavelet/internal/db" "github.com/Rain-kl/Wavelet/internal/model" - "github.com/Rain-kl/Wavelet/internal/util" "github.com/gin-gonic/gin" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") const ( catImage = "图片" @@ -49,10 +48,10 @@ type fileStatsResponse struct { // @Tags admin // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=fileStatsResponse} "获取成功" -// @Failure 401 {object} util.ResponseAny "未登录" -// @Failure 403 {object} util.ResponseAny "无管理员权限" -// @Failure 500 {object} util.ResponseAny "内部错误" +// @Success 200 {object} response.Any{data=fileStatsResponse} "获取成功" +// @Failure 401 {object} response.Any "未登录" +// @Failure 403 {object} response.Any "无管理员权限" +// @Failure 500 {object} response.Any "内部错误" // @Router /api/v1/admin/uploads/stats [get] func GetFileStats(c *gin.Context) { ctx := c.Request.Context() @@ -67,7 +66,7 @@ func GetFileStats(c *gin.Context) { Where("status != ?", model.UploadStatusDeleted). Scan(&summary).Error if err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return } @@ -84,7 +83,7 @@ func GetFileStats(c *gin.Context) { Group("type"). Scan(&typeRaw).Error if err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return } @@ -113,7 +112,7 @@ func GetFileStats(c *gin.Context) { Where("status != ?", model.UploadStatusDeleted). Scan(&fileRaws).Error if err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return } @@ -154,7 +153,7 @@ func GetFileStats(c *gin.Context) { Where("status != ? AND created_at >= ?", model.UploadStatusDeleted, startTime). Scan(&trendRaws).Error if err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return } @@ -185,7 +184,7 @@ func GetFileStats(c *gin.Context) { }) } - c.JSON(http.StatusOK, util.OK(fileStatsResponse{ + c.JSON(http.StatusOK, response.OK(fileStatsResponse{ TotalCount: summary.TotalCount, TotalSize: summary.TotalSize, Trend: trend, diff --git a/internal/apps/user/access_tokens.go b/internal/apps/user/access_tokens.go index c6859232..e128a981 100644 --- a/internal/apps/user/access_tokens.go +++ b/internal/apps/user/access_tokens.go @@ -5,8 +5,7 @@ // Package user 提供用户认证与帐户管理功能 package user -import ( - "net/http" +import ("net/http" "strconv" "strings" @@ -15,7 +14,8 @@ import ( "github.com/Rain-kl/Wavelet/internal/model" "github.com/Rain-kl/Wavelet/internal/util" "github.com/gin-gonic/gin" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") type createTokenRequest struct { Name string `json:"name"` @@ -33,8 +33,8 @@ type tokenResponse struct { // @Tags user // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=[]model.AccessToken} "令牌列表" -// @Failure 401 {object} util.ResponseAny "未登录" +// @Success 200 {object} response.Any{data=[]model.AccessToken} "令牌列表" +// @Failure 401 {object} response.Any "未登录" // @Router /api/v1/user/access-tokens [get] // ListAccessTokens 获取当前用户的 AccessToken 列表 func ListAccessTokens(c *gin.Context) { @@ -43,11 +43,11 @@ func ListAccessTokens(c *gin.Context) { var tokens []model.AccessToken if err := db.DB(ctx).Where("user_id = ?", currUser.ID).Order("created_at desc").Find(&tokens).Error; err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(tokens)) + c.JSON(http.StatusOK, response.OK(tokens)) } // CreateAccessToken 创建一个新的 AccessToken @@ -58,8 +58,8 @@ func ListAccessTokens(c *gin.Context) { // @Produce json // @Param request body user.createTokenRequest true "令牌名称" // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=user.tokenResponse} "新建令牌成功" -// @Failure 400 {object} util.ResponseAny "参数错误或超限" +// @Success 200 {object} response.Any{data=user.tokenResponse} "新建令牌成功" +// @Failure 400 {object} response.Any "参数错误或超限" // @Router /api/v1/user/access-tokens [post] func CreateAccessToken(c *gin.Context) { currUser, _ := util.GetFromContext[*model.User](c, oauth.UserObjKey) @@ -67,19 +67,19 @@ func CreateAccessToken(c *gin.Context) { var req createTokenRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusOK, util.Err(errBindParamsFailed)) + c.JSON(http.StatusOK, response.Err(errBindParamsFailed)) return } req.Name = strings.TrimSpace(req.Name) if req.Name == "" { - c.JSON(http.StatusOK, util.Err(errTokenNameRequired)) + c.JSON(http.StatusOK, response.Err(errTokenNameRequired)) return } // 只有管理员才能创建具有管理员权限的令牌 if req.IsAdmin && !currUser.IsAdmin { - c.JSON(http.StatusOK, util.Err(errAdminTokenRequiresAdmin)) + c.JSON(http.StatusOK, response.Err(errAdminTokenRequiresAdmin)) return } @@ -91,19 +91,19 @@ func CreateAccessToken(c *gin.Context) { var count int64 if err := db.DB(ctx).Model(&model.AccessToken{}).Where("user_id = ?", currUser.ID).Count(&count).Error; err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return } if int(count) >= maxLimit { - c.JSON(http.StatusOK, util.Err(errAccessTokenLimitReached)) + c.JSON(http.StatusOK, response.Err(errAccessTokenLimitReached)) return } // 生成 Token tokenStr, err := model.GenerateTokenString() if err != nil { - c.JSON(http.StatusOK, util.Err(errGenerateTokenFailed)) + c.JSON(http.StatusOK, response.Err(errGenerateTokenFailed)) return } @@ -119,11 +119,11 @@ func CreateAccessToken(c *gin.Context) { } if err := db.DB(ctx).Create(&tokenRecord).Error; err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(tokenResponse{ + c.JSON(http.StatusOK, response.OK(tokenResponse{ Token: tokenStr, Record: tokenRecord, })) @@ -136,8 +136,8 @@ func CreateAccessToken(c *gin.Context) { // @Produce json // @Param id path string true "令牌ID" // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=string} "删除成功" -// @Failure 400 {object} util.ResponseAny "参数错误" +// @Success 200 {object} response.Any{data=string} "删除成功" +// @Failure 400 {object} response.Any "参数错误" // @Router /api/v1/user/access-tokens/{id} [delete] func DeleteAccessToken(c *gin.Context) { currUser, _ := util.GetFromContext[*model.User](c, oauth.UserObjKey) @@ -146,22 +146,22 @@ func DeleteAccessToken(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { - c.JSON(http.StatusOK, util.Err(errInvalidTokenID)) + c.JSON(http.StatusOK, response.Err(errInvalidTokenID)) return } tx := db.DB(ctx).Where("id = ? AND user_id = ?", id, currUser.ID).Delete(&model.AccessToken{}) if tx.Error != nil { - c.JSON(http.StatusOK, util.Err(tx.Error.Error())) + c.JSON(http.StatusOK, response.Err(tx.Error.Error())) return } if tx.RowsAffected == 0 { - c.JSON(http.StatusOK, util.Err(errTokenNotFoundOrForbidden)) + c.JSON(http.StatusOK, response.Err(errTokenNotFoundOrForbidden)) return } - c.JSON(http.StatusOK, util.OK("删除成功")) + c.JSON(http.StatusOK, response.OK("删除成功")) } // RotateAccessToken 轮换一个 AccessToken @@ -171,8 +171,8 @@ func DeleteAccessToken(c *gin.Context) { // @Produce json // @Param id path string true "令牌ID" // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=user.tokenResponse} "令牌轮换成功" -// @Failure 400 {object} util.ResponseAny "参数错误" +// @Success 200 {object} response.Any{data=user.tokenResponse} "令牌轮换成功" +// @Failure 400 {object} response.Any "参数错误" // @Router /api/v1/user/access-tokens/{id}/rotate [post] func RotateAccessToken(c *gin.Context) { currUser, _ := util.GetFromContext[*model.User](c, oauth.UserObjKey) @@ -181,20 +181,20 @@ func RotateAccessToken(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { - c.JSON(http.StatusOK, util.Err(errInvalidTokenID)) + c.JSON(http.StatusOK, response.Err(errInvalidTokenID)) return } var tokenRecord model.AccessToken if err := db.DB(ctx).Where("id = ? AND user_id = ?", id, currUser.ID).First(&tokenRecord).Error; err != nil { - c.JSON(http.StatusOK, util.Err(errTokenNotFoundOrForbidden)) + c.JSON(http.StatusOK, response.Err(errTokenNotFoundOrForbidden)) return } // 生成新的 Token newTokenStr, err := model.GenerateTokenString() if err != nil { - c.JSON(http.StatusOK, util.Err(errGenerateTokenFailed)) + c.JSON(http.StatusOK, response.Err(errGenerateTokenFailed)) return } @@ -205,11 +205,11 @@ func RotateAccessToken(c *gin.Context) { tokenRecord.MaskedToken = newMaskedToken if err := db.DB(ctx).Save(&tokenRecord).Error; err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK(tokenResponse{ + c.JSON(http.StatusOK, response.OK(tokenResponse{ Token: newTokenStr, Record: tokenRecord, })) diff --git a/internal/apps/user/logics.go b/internal/apps/user/logics.go index 8a1f2c32..02923f41 100644 --- a/internal/apps/user/logics.go +++ b/internal/apps/user/logics.go @@ -3,8 +3,7 @@ package user -import ( - "context" +import ("context" "crypto/rand" "encoding/json" "errors" @@ -22,7 +21,8 @@ import ( "github.com/Rain-kl/Wavelet/internal/util" pkgu "github.com/Rain-kl/Wavelet/pkg/util" "github.com/gin-gonic/gin" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") type sendEmailCodeRequest struct { Email string `json:"email" binding:"required,email"` @@ -139,7 +139,7 @@ func verifyEmailCode(ctx context.Context, email, scene, code string) bool { func handleLoginEmailVerification(ctx context.Context, c *gin.Context, req *loginRequest, user *model.User) error { if req.Code != "" { if !verifyEmailCode(ctx, user.Email, "login", req.Code) { - c.JSON(http.StatusOK, util.Err(errEmailCodeInvalidOrExpired)) + c.JSON(http.StatusOK, response.Err(errEmailCodeInvalidOrExpired)) return errors.New("handled") } return nil @@ -149,7 +149,7 @@ func handleLoginEmailVerification(ctx context.Context, c *gin.Context, req *logi if !isSMTPConfigured(ctx) || user.Email == "" { codeKey := getEmailCodeKey("login", user.Email) if err := db.SetJSON(ctx, codeKey, "888888", emailCodeExpiry); err != nil { - c.JSON(http.StatusOK, util.Err(errGenerateEmailCodeFailed)) + c.JSON(http.StatusOK, response.Err(errGenerateEmailCodeFailed)) return errors.New("handled") } var msg string @@ -158,7 +158,7 @@ func handleLoginEmailVerification(ctx context.Context, c *gin.Context, req *logi } else { msg = errSMTPInvalidUseTempCodePrefix + "该账号未绑定邮箱,使用临时码登录" } - c.JSON(http.StatusOK, util.Err(msg)) + c.JSON(http.StatusOK, response.Err(msg)) return errors.New("handled") } @@ -167,13 +167,13 @@ func handleLoginEmailVerification(ctx context.Context, c *gin.Context, req *logi err := db.GetJSON(ctx, cooldownKey, &temp) if err != nil { if err := sendEmailVerificationCode(ctx, user.Email, "login", "login_email"); err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return errors.New("handled") } } maskedEmail := pkgu.MaskEmail(user.Email) - c.JSON(http.StatusOK, util.Err(errNeedEmailCodePrefix+maskedEmail)) + c.JSON(http.StatusOK, response.Err(errNeedEmailCodePrefix+maskedEmail)) return errors.New("handled") } @@ -184,24 +184,24 @@ func handleLoginEmailVerification(ctx context.Context, c *gin.Context, req *logi // @Accept json // @Produce json // @Param request body user.sendEmailCodeRequest true "发送验证码请求参数" -// @Success 200 {object} util.ResponseAny "发送成功" -// @Failure 400 {object} util.ResponseAny "参数错误" +// @Success 200 {object} response.Any "发送成功" +// @Failure 400 {object} response.Any "参数错误" // @Router /api/v1/user/send-email-code [post] func SendEmailCode(c *gin.Context) { var req sendEmailCodeRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } req.Email = strings.TrimSpace(req.Email) if req.Email == "" { - c.JSON(http.StatusOK, util.Err(errEmailRequired)) + c.JSON(http.StatusOK, response.Err(errEmailRequired)) return } if req.Scene != "register" { - c.JSON(http.StatusOK, util.Err(errUnsupportedEmailScene)) + c.JSON(http.StatusOK, response.Err(errUnsupportedEmailScene)) return } @@ -209,11 +209,11 @@ func SendEmailCode(c *gin.Context) { var count int64 if err := db.DB(ctx).Model(&model.User{}).Where("email = ?", req.Email).Count(&count).Error; err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return } if count > 0 { - c.JSON(http.StatusOK, util.Err(errEmailAlreadyRegistered)) + c.JSON(http.StatusOK, response.Err(errEmailAlreadyRegistered)) return } @@ -221,16 +221,16 @@ func SendEmailCode(c *gin.Context) { var temp string err := db.GetJSON(ctx, cooldownKey, &temp) if err == nil { - c.JSON(http.StatusOK, util.Err(errEmailCodeCooldown)) + c.JSON(http.StatusOK, response.Err(errEmailCodeCooldown)) return } if err := sendEmailVerificationCode(ctx, req.Email, "register", "register_email"); err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OKNil()) + c.JSON(http.StatusOK, response.OKNil()) } func validateRegisterEmailVerification(ctx context.Context, req *registerRequest) error { @@ -264,44 +264,44 @@ type updateProfileRequest struct { // @Accept json // @Produce json // @Param request body user.updateProfileRequest true "更新请求参数" -// @Success 200 {object} util.ResponseAny{data=oauth.BasicUserInfo} "修改成功,返回更新后的用户信息" -// @Failure 400 {object} util.ResponseAny "邮箱已被占用或参数错误" -// @Failure 401 {object} util.ResponseAny "未登录" +// @Success 200 {object} response.Any{data=oauth.BasicUserInfo} "修改成功,返回更新后的用户信息" +// @Failure 400 {object} response.Any "邮箱已被占用或参数错误" +// @Failure 401 {object} response.Any "未登录" // @Router /api/v1/user/profile [put] func UpdateProfile(c *gin.Context) { var req updateProfileRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } userObj, _ := util.GetFromContext[*model.User](c, oauth.UserObjKey) if userObj == nil { - c.JSON(http.StatusUnauthorized, util.Err(errLoginRequired)) + c.JSON(http.StatusUnauthorized, response.Err(errLoginRequired)) return } ctx := c.Request.Context() var dbUser model.User if err := db.DB(ctx).Where("id = ?", userObj.ID).First(&dbUser).Error; err != nil { - c.JSON(http.StatusOK, util.Err(errUserNotFound)) + c.JSON(http.StatusOK, response.Err(errUserNotFound)) return } req.Email = strings.TrimSpace(req.Email) if req.Email != "" && req.Email != dbUser.Email { if !strings.Contains(req.Email, "@") || !strings.Contains(req.Email, ".") { - c.JSON(http.StatusOK, util.Err(errEmailFormatInvalid)) + c.JSON(http.StatusOK, response.Err(errEmailFormatInvalid)) return } var count int64 if err := db.DB(ctx).Model(&model.User{}).Where("email = ? AND id != ?", req.Email, dbUser.ID).Count(&count).Error; err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return } if count > 0 { - c.JSON(http.StatusOK, util.Err(errEmailAlreadyBound)) + c.JSON(http.StatusOK, response.Err(errEmailAlreadyBound)) return } } @@ -319,12 +319,12 @@ func UpdateProfile(c *gin.Context) { dbUser.Location = strings.TrimSpace(req.Location) if err := db.DB(ctx).Save(&dbUser).Error; err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return } session := sessions.Default(c) needChange := session.Get("need_change_password") == true - c.JSON(http.StatusOK, util.OK(oauth.BuildBasicUserInfo(&dbUser, needChange))) + c.JSON(http.StatusOK, response.OK(oauth.BuildBasicUserInfo(&dbUser, needChange))) } diff --git a/internal/apps/user/routers.go b/internal/apps/user/routers.go index d0797efa..fad35df2 100644 --- a/internal/apps/user/routers.go +++ b/internal/apps/user/routers.go @@ -3,8 +3,7 @@ package user -import ( - "context" +import ("context" "net/http" "strings" "time" @@ -20,6 +19,7 @@ import ( "github.com/Rain-kl/Wavelet/pkg/logger" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" + "github.com/Rain-kl/Wavelet/internal/common/response" ) type loginRequest struct { @@ -83,14 +83,14 @@ func setLoginSession(ctx context.Context, c *gin.Context, user *model.User) erro isSessionCookie = true } } - session.Options(util.GetSessionOptions(maxAge)) + session.Options(oauth.GetSessionOptions(maxAge)) if err := session.Save(); err != nil { return err } if isSessionCookie { - util.StripCookieMaxAgeAndExpires(c.Writer.Header(), config.Config.App.SessionCookieName) + oauth.StripCookieMaxAgeAndExpires(c.Writer.Header(), config.Config.App.SessionCookieName) } return nil @@ -103,23 +103,23 @@ func setLoginSession(ctx context.Context, c *gin.Context, user *model.User) erro // @Accept json // @Produce json // @Param request body user.loginRequest true "登录请求参数" -// @Success 200 {object} util.ResponseAny{data=oauth.BasicUserInfo} "登录成功,返回用户信息" -// @Failure 400 {object} util.ResponseAny "用户名或密码错误、帐号已禁用等" -// @Failure 500 {object} util.ResponseAny "服务内部错误" +// @Success 200 {object} response.Any{data=oauth.BasicUserInfo} "登录成功,返回用户信息" +// @Failure 400 {object} response.Any "用户名或密码错误、帐号已禁用等" +// @Failure 500 {object} response.Any "服务内部错误" // @Router /api/v1/user/login [post] func Login(c *gin.Context) { if !isPasswordLoginEnabled() { - c.JSON(http.StatusOK, util.Err(errPasswordLoginDisabled)) + c.JSON(http.StatusOK, response.Err(errPasswordLoginDisabled)) return } var req loginRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } req.Username = strings.TrimSpace(req.Username) if req.Username == "" || req.Password == "" { - c.JSON(http.StatusOK, util.Err(errInvalidParams)) + c.JSON(http.StatusOK, response.Err(errInvalidParams)) return } @@ -127,12 +127,12 @@ func Login(c *gin.Context) { ctx := c.Request.Context() if err := db.DB(ctx).Where("username = ? OR email = ?", req.Username, req.Username).First(&user).Error; err != nil { logger.WarnF(ctx, "[LoginAudit] failed login attempt (username not found) for input: %s, IP: %s", req.Username, c.ClientIP()) - c.JSON(http.StatusOK, util.Err(errUsernameOrPasswordWrong)) + c.JSON(http.StatusOK, response.Err(errUsernameOrPasswordWrong)) return } if !user.IsActive { logger.WarnF(ctx, "[LoginAudit] banned user login attempt for username: %s, ID: %d, IP: %s", user.Username, user.ID, c.ClientIP()) - c.JSON(http.StatusOK, util.Err(common.BannedAccount)) + c.JSON(http.StatusOK, response.Err(common.BannedAccount)) return } @@ -141,7 +141,7 @@ func Login(c *gin.Context) { if !user.CheckPassword(req.Password) { logger.WarnF(ctx, "[LoginAudit] failed login attempt (incorrect password) for username: %s, ID: %d, IP: %s", user.Username, user.ID, c.ClientIP()) - c.JSON(http.StatusOK, util.Err(errUsernameOrPasswordWrong)) + c.JSON(http.StatusOK, response.Err(errUsernameOrPasswordWrong)) return } @@ -162,11 +162,11 @@ func Login(c *gin.Context) { user.LastLoginAt = time.Now() if err := db.DB(ctx).Model(&user).Update("last_login_at", user.LastLoginAt).Error; err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return } if err := setLoginSession(ctx, c, &user); err != nil { - c.JSON(http.StatusOK, util.Err(errSaveSessionFailed)) + c.JSON(http.StatusOK, response.Err(errSaveSessionFailed)) return } @@ -174,7 +174,7 @@ func Login(c *gin.Context) { custom_events.TriggerAdminLoginEvent(ctx, &user, c.ClientIP()) - c.JSON(http.StatusOK, util.OK(oauth.BuildBasicUserInfo(&user, needChangePassword))) + c.JSON(http.StatusOK, response.OK(oauth.BuildBasicUserInfo(&user, needChangePassword))) } // Register 用户注册 @@ -184,19 +184,19 @@ func Login(c *gin.Context) { // @Accept json // @Produce json // @Param request body user.registerRequest true "注册请求参数" -// @Success 200 {object} util.ResponseAny{data=oauth.BasicUserInfo} "注册并登录成功,返回用户信息" -// @Failure 400 {object} util.ResponseAny "参数错误、用户名已存在或注册已关闭" -// @Failure 500 {object} util.ResponseAny "服务内部错误" +// @Success 200 {object} response.Any{data=oauth.BasicUserInfo} "注册并登录成功,返回用户信息" +// @Failure 400 {object} response.Any "参数错误、用户名已存在或注册已关闭" +// @Failure 500 {object} response.Any "服务内部错误" // @Router /api/v1/user/register [post] func Register(c *gin.Context) { if !isRegistrationEnabled() || !isPasswordRegisterEnabled() { - c.JSON(http.StatusOK, util.Err(errRegistrationDisabled)) + c.JSON(http.StatusOK, response.Err(errRegistrationDisabled)) return } var req registerRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -208,15 +208,15 @@ func Register(c *gin.Context) { req.Code = strings.TrimSpace(req.Code) if req.Username == "" || req.Password == "" { - c.JSON(http.StatusOK, util.Err(errInvalidParams)) + c.JSON(http.StatusOK, response.Err(errInvalidParams)) return } if req.Email == "" { - c.JSON(http.StatusOK, util.Err(errEmailRequired)) + c.JSON(http.StatusOK, response.Err(errEmailRequired)) return } if len(req.Password) < minPasswordLength { - c.JSON(http.StatusOK, util.Err(errPasswordTooShort)) + c.JSON(http.StatusOK, response.Err(errPasswordTooShort)) return } @@ -224,7 +224,7 @@ func Register(c *gin.Context) { // 邮箱注册验证校验 if err := validateRegisterEmailVerification(ctx, &req); err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return } @@ -245,21 +245,21 @@ func Register(c *gin.Context) { user.Nickname = req.Username } if err := user.SetEncryptedPassword(req.Password); err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return } if err := user.RegisterUser(ctx, db.DB(ctx)); err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return } if err := setLoginSession(ctx, c, &user); err != nil { - c.JSON(http.StatusOK, util.Err(errSaveSessionFailed)) + c.JSON(http.StatusOK, response.Err(errSaveSessionFailed)) return } - c.JSON(http.StatusOK, util.OK(oauth.BuildBasicUserInfo(&user, false))) + c.JSON(http.StatusOK, response.OK(oauth.BuildBasicUserInfo(&user, false))) } // Logout 用户退出登录 @@ -268,8 +268,8 @@ func Register(c *gin.Context) { // @Tags user // @Produce json // @Security SessionCookie -// @Success 200 {object} util.ResponseAny{data=string} "退出成功" -// @Failure 500 {object} util.ResponseAny "Session 清除失败" +// @Success 200 {object} response.Any{data=string} "退出成功" +// @Failure 500 {object} response.Any "Session 清除失败" // @Router /api/v1/user/logout [get] func Logout(c *gin.Context) { session := sessions.Default(c) @@ -278,13 +278,13 @@ func Logout(c *gin.Context) { if userID != nil { logger.InfoF(c.Request.Context(), "[LoginAudit] user logged out: %v, ID: %v, IP: %s", username, userID, c.ClientIP()) } - session.Options(util.GetSessionOptions(-1)) + session.Options(oauth.GetSessionOptions(-1)) session.Clear() if err := session.Save(); err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return } - c.JSON(http.StatusOK, util.OK("")) + c.JSON(http.StatusOK, response.OK("")) } type changePasswordRequest struct { @@ -299,14 +299,14 @@ type changePasswordRequest struct { // @Accept json // @Produce json // @Param request body user.changePasswordRequest true "修改密码请求参数" -// @Success 200 {object} util.ResponseAny{data=string} "修改密码成功" -// @Failure 400 {object} util.ResponseAny "原密码错误或新密码不符合要求" -// @Failure 401 {object} util.ResponseAny "请先登录" +// @Success 200 {object} response.Any{data=string} "修改密码成功" +// @Failure 400 {object} response.Any "原密码错误或新密码不符合要求" +// @Failure 401 {object} response.Any "请先登录" // @Router /api/v1/user/change-password [post] func ChangePassword(c *gin.Context) { var req changePasswordRequest if err := c.ShouldBindJSON(&req); err != nil { - c.JSON(http.StatusBadRequest, util.Err(err.Error())) + c.JSON(http.StatusBadRequest, response.Err(err.Error())) return } @@ -314,47 +314,47 @@ func ChangePassword(c *gin.Context) { req.NewPassword = strings.TrimSpace(req.NewPassword) if req.OldPassword == "" || req.NewPassword == "" { - c.JSON(http.StatusOK, util.Err(errInvalidParams)) + c.JSON(http.StatusOK, response.Err(errInvalidParams)) return } if len(req.NewPassword) < minPasswordLength { - c.JSON(http.StatusOK, util.Err(errNewPasswordTooShort)) + c.JSON(http.StatusOK, response.Err(errNewPasswordTooShort)) return } userObj, _ := util.GetFromContext[*model.User](c, oauth.UserObjKey) if userObj == nil { - c.JSON(http.StatusUnauthorized, util.Err(errLoginRequired)) + c.JSON(http.StatusUnauthorized, response.Err(errLoginRequired)) return } ctx := c.Request.Context() var dbUser model.User if err := db.DB(ctx).Where("id = ?", userObj.ID).First(&dbUser).Error; err != nil { - c.JSON(http.StatusOK, util.Err(errUserNotFound)) + c.JSON(http.StatusOK, response.Err(errUserNotFound)) return } // 校验旧密码 if !dbUser.CheckPassword(req.OldPassword) { - c.JSON(http.StatusOK, util.Err(errOldPasswordIncorrect)) + c.JSON(http.StatusOK, response.Err(errOldPasswordIncorrect)) return } // 加密并更新为新密码 if err := dbUser.SetEncryptedPassword(req.NewPassword); err != nil { - c.JSON(http.StatusOK, util.Err(errPasswordEncryptFailed)) + c.JSON(http.StatusOK, response.Err(errPasswordEncryptFailed)) return } if err := db.DB(ctx).Model(&dbUser).Update("password", dbUser.Password).Error; err != nil { - c.JSON(http.StatusOK, util.Err(err.Error())) + c.JSON(http.StatusOK, response.Err(err.Error())) return } // 吊销该用户所有的 Access Token if err := db.DB(ctx).Where("user_id = ?", dbUser.ID).Delete(&model.AccessToken{}).Error; err != nil { - c.JSON(http.StatusOK, util.Err("吊销 Access Token 失败: "+err.Error())) + c.JSON(http.StatusOK, response.Err("吊销 Access Token 失败: "+err.Error())) return } @@ -363,5 +363,5 @@ func ChangePassword(c *gin.Context) { session.Clear() _ = session.Save() - c.JSON(http.StatusOK, util.OK("密码修改成功")) + c.JSON(http.StatusOK, response.OK("密码修改成功")) } diff --git a/internal/apps/user/routers_test.go b/internal/apps/user/routers_test.go index eb566ffa..b0fce8e4 100644 --- a/internal/apps/user/routers_test.go +++ b/internal/apps/user/routers_test.go @@ -3,8 +3,7 @@ package user -import ( - "bytes" +import ("bytes" "context" "encoding/json" "net/http" @@ -18,11 +17,11 @@ import ( "github.com/Rain-kl/Wavelet/internal/db" "github.com/Rain-kl/Wavelet/internal/model" "github.com/Rain-kl/Wavelet/internal/testhelper" - "github.com/Rain-kl/Wavelet/internal/util" "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/cookie" "github.com/gin-gonic/gin" -) + + "github.com/Rain-kl/Wavelet/internal/common/response") func setupUserTestRouter(t *testing.T) *gin.Engine { t.Helper() @@ -49,7 +48,7 @@ func setupUserTestRouter(t *testing.T) *gin.Engine { gin.SetMode(gin.TestMode) r := gin.New() store := cookie.NewStore([]byte(config.Config.App.SessionSecret)) - store.Options(util.GetSessionOptions(3600)) + store.Options(oauth.GetSessionOptions(3600)) r.Use(sessions.Sessions(config.Config.App.SessionCookieName, store)) api := r.Group("/api/v1") @@ -92,7 +91,7 @@ func sessionCookieFromResponse(t *testing.T, w *httptest.ResponseRecorder) *http func basicUserInfoFromResponse(t *testing.T, w *httptest.ResponseRecorder) oauth.BasicUserInfo { t.Helper() - var resp util.ResponseAny + var resp response.Any if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil { t.Fatalf("basicUserInfoFromResponse() decode response failed: %v", err) } diff --git a/internal/util/response.go b/internal/common/response/response.go similarity index 81% rename from internal/util/response.go rename to internal/common/response/response.go index fd77a4df..f17b1770 100644 --- a/internal/util/response.go +++ b/internal/common/response/response.go @@ -2,7 +2,8 @@ // Copyright 2026 Arctel.net // SPDX-License-Identifier: Apache-2.0 -package util +// Package response provides shared HTTP API response structures. +package response // Response 通用响应体 type Response[T any] struct { @@ -10,9 +11,9 @@ type Response[T any] struct { Data T `json:"data"` } -// ResponseAny 用于 Swagger 文档的响应类型(非泛型) +// Any 用于 Swagger 文档的响应类型(非泛型) // swag 不支持泛型,使用此类型替代 Response[T] -type ResponseAny struct { +type Any struct { ErrorMsg string `json:"error_msg" example:""` Data interface{} `json:"data"` } diff --git a/internal/router/router.go b/internal/router/router.go index 6a977570..42d8a1f9 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -33,7 +33,6 @@ import ( "github.com/Rain-kl/Wavelet/internal/apps/upload" "github.com/Rain-kl/Wavelet/internal/apps/user" "github.com/Rain-kl/Wavelet/internal/model" - "github.com/Rain-kl/Wavelet/internal/util" capUtil "github.com/Rain-kl/Wavelet/internal/service/cap" // Swagger 文档生成 @@ -98,7 +97,7 @@ func Serve() { } } - sessionStore.Options(util.GetSessionOptions(config.Config.App.SessionAge)) + sessionStore.Options(oauth.GetSessionOptions(config.Config.App.SessionAge)) r.Use(sessions.Sessions(config.Config.App.SessionCookieName, sessionStore))