diff --git a/docs/docs.go b/docs/docs.go index 385a749..db216bf 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -165,7 +165,116 @@ const docTemplate = `{ } } }, - "/admin/batch/{batch_id}": { + "/admin/api-tokens/{id}/revoke": { + "post": { + "security": [ + { + "AdminAuth": [] + } + ], + "description": "将 API Token 标记为已撤销,使其失效但保留记录", + "produces": [ + "application/json" + ], + "tags": [ + "Admin" + ], + "summary": "撤销 API Token", + "parameters": [ + { + "type": "integer", + "description": "Token ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/model.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/model.Response" + } + } + } + } + }, + "/admin/batches": { + "get": { + "security": [ + { + "AdminAuth": [] + } + ], + "description": "分页查询所有文件批次,支持按状态过滤和取件码模糊搜索", + "produces": [ + "application/json" + ], + "tags": [ + "Admin" + ], + "summary": "获取批次列表", + "parameters": [ + { + "type": "integer", + "description": "页码 (默认 1)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页数量 (默认 20)", + "name": "page_size", + "in": "query" + }, + { + "type": "string", + "description": "状态 (active/expired/deleted)", + "name": "status", + "in": "query" + }, + { + "type": "string", + "description": "取件码 (模糊搜索)", + "name": "pickup_code", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/model.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/admin.ListBatchesResponse" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/model.Response" + } + } + } + } + }, + "/admin/batches/{batch_id}": { "get": { "security": [ { @@ -317,75 +426,6 @@ const docTemplate = `{ } } }, - "/admin/batches": { - "get": { - "security": [ - { - "AdminAuth": [] - } - ], - "description": "分页查询所有文件批次,支持按状态过滤和取件码模糊搜索", - "produces": [ - "application/json" - ], - "tags": [ - "Admin" - ], - "summary": "获取批次列表", - "parameters": [ - { - "type": "integer", - "description": "页码 (默认 1)", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "每页数量 (默认 20)", - "name": "page_size", - "in": "query" - }, - { - "type": "string", - "description": "状态 (active/expired/deleted)", - "name": "status", - "in": "query" - }, - { - "type": "string", - "description": "取件码 (模糊搜索)", - "name": "pickup_code", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/model.Response" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/admin.ListBatchesResponse" - } - } - } - ] - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/model.Response" - } - } - } - } - }, "/admin/login": { "post": { "description": "通过密码换取 JWT Token", @@ -438,130 +478,7 @@ const docTemplate = `{ } } }, - "/api/download/batch/{pickup_code}": { - "get": { - "description": "根据取件码将批次内的所有文件打包为 ZIP 格式一次性下载", - "produces": [ - "application/zip" - ], - "tags": [ - "Public" - ], - "summary": "批量下载文件", - "parameters": [ - { - "type": "string", - "description": "取件码", - "name": "pickup_code", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "file" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/model.Response" - } - } - } - } - }, - "/api/download/file/{file_id}": { - "get": { - "description": "根据文件 ID 下载单个文件", - "produces": [ - "application/octet-stream" - ], - "tags": [ - "Public" - ], - "summary": "下载单个文件", - "parameters": [ - { - "type": "integer", - "description": "文件 ID", - "name": "file_id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "file" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/model.Response" - } - }, - "410": { - "description": "Gone", - "schema": { - "$ref": "#/definitions/model.Response" - } - } - } - } - }, - "/api/pickup/{pickup_code}": { - "get": { - "description": "根据取件码获取文件批次详详情和文件列表", - "produces": [ - "application/json" - ], - "tags": [ - "Public" - ], - "summary": "获取批次信息", - "parameters": [ - { - "type": "string", - "description": "取件码", - "name": "pickup_code", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/model.Response" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/public.PickupResponse" - } - } - } - ] - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/model.Response" - } - } - } - } - }, - "/api/upload": { + "/api/batches": { "post": { "description": "上传一个或多个文件并创建一个提取批次", "consumes": [ @@ -641,7 +558,7 @@ const docTemplate = `{ } } }, - "/api/upload/text": { + "/api/batches/text": { "post": { "description": "中转一段长文本内容并创建一个提取批次", "consumes": [ @@ -698,6 +615,129 @@ const docTemplate = `{ } } } + }, + "/api/batches/{pickup_code}": { + "get": { + "description": "根据取件码获取文件批次详详情和文件列表", + "produces": [ + "application/json" + ], + "tags": [ + "Public" + ], + "summary": "获取批次信息", + "parameters": [ + { + "type": "string", + "description": "取件码", + "name": "pickup_code", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/model.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/public.PickupResponse" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/model.Response" + } + } + } + } + }, + "/api/batches/{pickup_code}/download": { + "get": { + "description": "根据取件码将批次内的所有文件打包为 ZIP 格式一次性下载", + "produces": [ + "application/zip" + ], + "tags": [ + "Public" + ], + "summary": "批量下载文件", + "parameters": [ + { + "type": "string", + "description": "取件码", + "name": "pickup_code", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/model.Response" + } + } + } + } + }, + "/api/files/{file_id}/download": { + "get": { + "description": "根据文件 ID 下载单个文件", + "produces": [ + "application/octet-stream" + ], + "tags": [ + "Public" + ], + "summary": "下载单个文件", + "parameters": [ + { + "type": "integer", + "description": "文件 ID", + "name": "file_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/model.Response" + } + }, + "410": { + "description": "Gone", + "schema": { + "$ref": "#/definitions/model.Response" + } + } + } + } } }, "definitions": { diff --git a/docs/swagger.json b/docs/swagger.json index abc3317..024dc39 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -158,7 +158,116 @@ } } }, - "/admin/batch/{batch_id}": { + "/admin/api-tokens/{id}/revoke": { + "post": { + "security": [ + { + "AdminAuth": [] + } + ], + "description": "将 API Token 标记为已撤销,使其失效但保留记录", + "produces": [ + "application/json" + ], + "tags": [ + "Admin" + ], + "summary": "撤销 API Token", + "parameters": [ + { + "type": "integer", + "description": "Token ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/model.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/model.Response" + } + } + } + } + }, + "/admin/batches": { + "get": { + "security": [ + { + "AdminAuth": [] + } + ], + "description": "分页查询所有文件批次,支持按状态过滤和取件码模糊搜索", + "produces": [ + "application/json" + ], + "tags": [ + "Admin" + ], + "summary": "获取批次列表", + "parameters": [ + { + "type": "integer", + "description": "页码 (默认 1)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页数量 (默认 20)", + "name": "page_size", + "in": "query" + }, + { + "type": "string", + "description": "状态 (active/expired/deleted)", + "name": "status", + "in": "query" + }, + { + "type": "string", + "description": "取件码 (模糊搜索)", + "name": "pickup_code", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/model.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/admin.ListBatchesResponse" + } + } + } + ] + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/model.Response" + } + } + } + } + }, + "/admin/batches/{batch_id}": { "get": { "security": [ { @@ -310,75 +419,6 @@ } } }, - "/admin/batches": { - "get": { - "security": [ - { - "AdminAuth": [] - } - ], - "description": "分页查询所有文件批次,支持按状态过滤和取件码模糊搜索", - "produces": [ - "application/json" - ], - "tags": [ - "Admin" - ], - "summary": "获取批次列表", - "parameters": [ - { - "type": "integer", - "description": "页码 (默认 1)", - "name": "page", - "in": "query" - }, - { - "type": "integer", - "description": "每页数量 (默认 20)", - "name": "page_size", - "in": "query" - }, - { - "type": "string", - "description": "状态 (active/expired/deleted)", - "name": "status", - "in": "query" - }, - { - "type": "string", - "description": "取件码 (模糊搜索)", - "name": "pickup_code", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/model.Response" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/admin.ListBatchesResponse" - } - } - } - ] - } - }, - "401": { - "description": "Unauthorized", - "schema": { - "$ref": "#/definitions/model.Response" - } - } - } - } - }, "/admin/login": { "post": { "description": "通过密码换取 JWT Token", @@ -431,130 +471,7 @@ } } }, - "/api/download/batch/{pickup_code}": { - "get": { - "description": "根据取件码将批次内的所有文件打包为 ZIP 格式一次性下载", - "produces": [ - "application/zip" - ], - "tags": [ - "Public" - ], - "summary": "批量下载文件", - "parameters": [ - { - "type": "string", - "description": "取件码", - "name": "pickup_code", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "file" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/model.Response" - } - } - } - } - }, - "/api/download/file/{file_id}": { - "get": { - "description": "根据文件 ID 下载单个文件", - "produces": [ - "application/octet-stream" - ], - "tags": [ - "Public" - ], - "summary": "下载单个文件", - "parameters": [ - { - "type": "integer", - "description": "文件 ID", - "name": "file_id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "file" - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/model.Response" - } - }, - "410": { - "description": "Gone", - "schema": { - "$ref": "#/definitions/model.Response" - } - } - } - } - }, - "/api/pickup/{pickup_code}": { - "get": { - "description": "根据取件码获取文件批次详详情和文件列表", - "produces": [ - "application/json" - ], - "tags": [ - "Public" - ], - "summary": "获取批次信息", - "parameters": [ - { - "type": "string", - "description": "取件码", - "name": "pickup_code", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/model.Response" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/public.PickupResponse" - } - } - } - ] - } - }, - "404": { - "description": "Not Found", - "schema": { - "$ref": "#/definitions/model.Response" - } - } - } - } - }, - "/api/upload": { + "/api/batches": { "post": { "description": "上传一个或多个文件并创建一个提取批次", "consumes": [ @@ -634,7 +551,7 @@ } } }, - "/api/upload/text": { + "/api/batches/text": { "post": { "description": "中转一段长文本内容并创建一个提取批次", "consumes": [ @@ -691,6 +608,129 @@ } } } + }, + "/api/batches/{pickup_code}": { + "get": { + "description": "根据取件码获取文件批次详详情和文件列表", + "produces": [ + "application/json" + ], + "tags": [ + "Public" + ], + "summary": "获取批次信息", + "parameters": [ + { + "type": "string", + "description": "取件码", + "name": "pickup_code", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/model.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/public.PickupResponse" + } + } + } + ] + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/model.Response" + } + } + } + } + }, + "/api/batches/{pickup_code}/download": { + "get": { + "description": "根据取件码将批次内的所有文件打包为 ZIP 格式一次性下载", + "produces": [ + "application/zip" + ], + "tags": [ + "Public" + ], + "summary": "批量下载文件", + "parameters": [ + { + "type": "string", + "description": "取件码", + "name": "pickup_code", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/model.Response" + } + } + } + } + }, + "/api/files/{file_id}/download": { + "get": { + "description": "根据文件 ID 下载单个文件", + "produces": [ + "application/octet-stream" + ], + "tags": [ + "Public" + ], + "summary": "下载单个文件", + "parameters": [ + { + "type": "integer", + "description": "文件 ID", + "name": "file_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/model.Response" + } + }, + "410": { + "description": "Gone", + "schema": { + "$ref": "#/definitions/model.Response" + } + } + } + } } }, "definitions": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index e815303..fbbf810 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -283,7 +283,73 @@ paths: summary: 删除 API Token tags: - Admin - /admin/batch/{batch_id}: + /admin/api-tokens/{id}/revoke: + post: + description: 将 API Token 标记为已撤销,使其失效但保留记录 + parameters: + - description: Token ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/model.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/model.Response' + security: + - AdminAuth: [] + summary: 撤销 API Token + tags: + - Admin + /admin/batches: + get: + description: 分页查询所有文件批次,支持按状态过滤和取件码模糊搜索 + parameters: + - description: 页码 (默认 1) + in: query + name: page + type: integer + - description: 每页数量 (默认 20) + in: query + name: page_size + type: integer + - description: 状态 (active/expired/deleted) + in: query + name: status + type: string + - description: 取件码 (模糊搜索) + in: query + name: pickup_code + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/model.Response' + - properties: + data: + $ref: '#/definitions/admin.ListBatchesResponse' + type: object + "401": + description: Unauthorized + schema: + $ref: '#/definitions/model.Response' + security: + - AdminAuth: [] + summary: 获取批次列表 + tags: + - Admin + /admin/batches/{batch_id}: delete: description: 标记批次为已删除,并物理删除关联的存储文件 parameters: @@ -374,47 +440,6 @@ paths: summary: 修改批次信息 tags: - Admin - /admin/batches: - get: - description: 分页查询所有文件批次,支持按状态过滤和取件码模糊搜索 - parameters: - - description: 页码 (默认 1) - in: query - name: page - type: integer - - description: 每页数量 (默认 20) - in: query - name: page_size - type: integer - - description: 状态 (active/expired/deleted) - in: query - name: status - type: string - - description: 取件码 (模糊搜索) - in: query - name: pickup_code - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - allOf: - - $ref: '#/definitions/model.Response' - - properties: - data: - $ref: '#/definitions/admin.ListBatchesResponse' - type: object - "401": - description: Unauthorized - schema: - $ref: '#/definitions/model.Response' - security: - - AdminAuth: [] - summary: 获取批次列表 - tags: - - Admin /admin/login: post: consumes: @@ -446,85 +471,7 @@ paths: summary: 管理员登录 tags: - Admin - /api/download/batch/{pickup_code}: - get: - description: 根据取件码将批次内的所有文件打包为 ZIP 格式一次性下载 - parameters: - - description: 取件码 - in: path - name: pickup_code - required: true - type: string - produces: - - application/zip - responses: - "200": - description: OK - schema: - type: file - "404": - description: Not Found - schema: - $ref: '#/definitions/model.Response' - summary: 批量下载文件 - tags: - - Public - /api/download/file/{file_id}: - get: - description: 根据文件 ID 下载单个文件 - parameters: - - description: 文件 ID - in: path - name: file_id - required: true - type: integer - produces: - - application/octet-stream - responses: - "200": - description: OK - schema: - type: file - "404": - description: Not Found - schema: - $ref: '#/definitions/model.Response' - "410": - description: Gone - schema: - $ref: '#/definitions/model.Response' - summary: 下载单个文件 - tags: - - Public - /api/pickup/{pickup_code}: - get: - description: 根据取件码获取文件批次详详情和文件列表 - parameters: - - description: 取件码 - in: path - name: pickup_code - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - allOf: - - $ref: '#/definitions/model.Response' - - properties: - data: - $ref: '#/definitions/public.PickupResponse' - type: object - "404": - description: Not Found - schema: - $ref: '#/definitions/model.Response' - summary: 获取批次信息 - tags: - - Public - /api/upload: + /api/batches: post: consumes: - multipart/form-data @@ -574,7 +521,58 @@ paths: summary: 上传文件 tags: - Public - /api/upload/text: + /api/batches/{pickup_code}: + get: + description: 根据取件码获取文件批次详详情和文件列表 + parameters: + - description: 取件码 + in: path + name: pickup_code + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/model.Response' + - properties: + data: + $ref: '#/definitions/public.PickupResponse' + type: object + "404": + description: Not Found + schema: + $ref: '#/definitions/model.Response' + summary: 获取批次信息 + tags: + - Public + /api/batches/{pickup_code}/download: + get: + description: 根据取件码将批次内的所有文件打包为 ZIP 格式一次性下载 + parameters: + - description: 取件码 + in: path + name: pickup_code + required: true + type: string + produces: + - application/zip + responses: + "200": + description: OK + schema: + type: file + "404": + description: Not Found + schema: + $ref: '#/definitions/model.Response' + summary: 批量下载文件 + tags: + - Public + /api/batches/text: post: consumes: - application/json @@ -609,6 +607,33 @@ paths: summary: 发送长文本 tags: - Public + /api/files/{file_id}/download: + get: + description: 根据文件 ID 下载单个文件 + parameters: + - description: 文件 ID + in: path + name: file_id + required: true + type: integer + produces: + - application/octet-stream + responses: + "200": + description: OK + schema: + type: file + "404": + description: Not Found + schema: + $ref: '#/definitions/model.Response' + "410": + description: Gone + schema: + $ref: '#/definitions/model.Response' + summary: 下载单个文件 + tags: + - Public securityDefinitions: AdminAuth: description: Type "Bearer " to authenticate. diff --git a/internal/api/admin/batch.go b/internal/api/admin/batch.go index 84046dd..e3e055f 100644 --- a/internal/api/admin/batch.go +++ b/internal/api/admin/batch.go @@ -97,7 +97,7 @@ func (h *BatchHandler) ListBatches(c *gin.Context) { // @Produce json // @Success 200 {object} model.Response{data=model.FileBatch} // @Failure 404 {object} model.Response -// @Router /admin/batch/{batch_id} [get] +// @Router /admin/batches/{batch_id} [get] func (h *BatchHandler) GetBatch(c *gin.Context) { id := c.Param("batch_id") var batch model.FileBatch @@ -119,7 +119,7 @@ func (h *BatchHandler) GetBatch(c *gin.Context) { // @Param request body UpdateBatchRequest true "修改内容" // @Success 200 {object} model.Response{data=model.FileBatch} // @Failure 400 {object} model.Response -// @Router /admin/batch/{batch_id} [put] +// @Router /admin/batches/{batch_id} [put] func (h *BatchHandler) UpdateBatch(c *gin.Context) { id := c.Param("batch_id") var batch model.FileBatch @@ -159,7 +159,7 @@ func (h *BatchHandler) UpdateBatch(c *gin.Context) { // @Produce json // @Success 200 {object} model.Response // @Failure 500 {object} model.Response -// @Router /admin/batch/{batch_id} [delete] +// @Router /admin/batches/{batch_id} [delete] func (h *BatchHandler) DeleteBatch(c *gin.Context) { idStr := c.Param("batch_id") id, _ := strconv.ParseUint(idStr, 10, 32) diff --git a/internal/api/admin/token.go b/internal/api/admin/token.go index 8416943..91a4a12 100644 --- a/internal/api/admin/token.go +++ b/internal/api/admin/token.go @@ -80,6 +80,16 @@ func (h *TokenHandler) CreateToken(c *gin.Context) { })) } +// RevokeToken 撤销 API Token +// @Summary 撤销 API Token +// @Description 将 API Token 标记为已撤销,使其失效但保留记录 +// @Tags Admin +// @Security AdminAuth +// @Param id path int true "Token ID" +// @Produce json +// @Success 200 {object} model.Response +// @Failure 500 {object} model.Response +// @Router /admin/api-tokens/{id}/revoke [post] func (h *TokenHandler) RevokeToken(c *gin.Context) { id := c.Param("id") if err := bootstrap.DB.Model(&model.APIToken{}).Where("id = ?", id).Update("revoked", true).Error; err != nil { diff --git a/internal/api/middleware/limit.go b/internal/api/middleware/limit.go index f5f2c3d..ecf49f8 100644 --- a/internal/api/middleware/limit.go +++ b/internal/api/middleware/limit.go @@ -26,7 +26,7 @@ func PickupRateLimit() gin.HandlerFunc { failureMutex.Unlock() if exists && count >= config.GlobalConfig.Security.PickupFailLimit { - c.JSON(http.StatusTooManyRequests, model.ErrorResponse(http.StatusTooManyRequests, "Too many failed attempts. Please try again later.")) + c.JSON(http.StatusTooManyRequests, model.ErrorResponse(model.CodeTooManyRequests, "Too many failed attempts. Please try again later.")) c.Abort() return } diff --git a/internal/api/public/pickup.go b/internal/api/public/pickup.go index 665c575..f8e95fb 100644 --- a/internal/api/public/pickup.go +++ b/internal/api/public/pickup.go @@ -35,7 +35,7 @@ type PickupResponse struct { // @Produce application/zip // @Success 200 {file} file // @Failure 404 {object} model.Response -// @Router /api/download/batch/{pickup_code} [get] +// @Router /api/batches/{pickup_code}/download [get] func (h *PickupHandler) DownloadBatch(c *gin.Context) { code := c.Param("pickup_code") batch, err := h.batchService.GetBatchByPickupCode(code) @@ -88,7 +88,7 @@ func NewPickupHandler() *PickupHandler { // @Param pickup_code path string true "取件码" // @Success 200 {object} model.Response{data=PickupResponse} // @Failure 404 {object} model.Response -// @Router /api/pickup/{pickup_code} [get] +// @Router /api/batches/{pickup_code} [get] func (h *PickupHandler) Pickup(c *gin.Context) { code := c.Param("pickup_code") if code == "" { @@ -124,7 +124,7 @@ func (h *PickupHandler) Pickup(c *gin.Context) { // @Success 200 {file} file // @Failure 404 {object} model.Response // @Failure 410 {object} model.Response -// @Router /api/download/file/{file_id} [get] +// @Router /api/files/{file_id}/download [get] func (h *PickupHandler) DownloadFile(c *gin.Context) { fileIDStr := c.Param("file_id") fileID, _ := strconv.ParseUint(fileIDStr, 10, 32) diff --git a/internal/api/public/upload.go b/internal/api/public/upload.go index abeb784..f297f2d 100644 --- a/internal/api/public/upload.go +++ b/internal/api/public/upload.go @@ -41,7 +41,7 @@ type UploadResponse struct { // @Success 200 {object} model.Response{data=UploadResponse} // @Failure 400 {object} model.Response // @Failure 500 {object} model.Response -// @Router /api/upload [post] +// @Router /api/batches [post] func (h *UploadHandler) Upload(c *gin.Context) { form, err := c.MultipartForm() if err != nil { @@ -113,7 +113,7 @@ type UploadTextRequest struct { // @Success 200 {object} model.Response{data=UploadResponse} // @Failure 400 {object} model.Response // @Failure 500 {object} model.Response -// @Router /api/upload/text [post] +// @Router /api/batches/text [post] func (h *UploadHandler) UploadText(c *gin.Context) { var req UploadTextRequest if err := c.ShouldBindJSON(&req); err != nil { diff --git a/internal/model/response.go b/internal/model/response.go index 33bc2d4..d18c148 100644 --- a/internal/model/response.go +++ b/internal/model/response.go @@ -9,13 +9,14 @@ type Response struct { // 错误码定义 const ( - CodeSuccess = 200 - CodeBadRequest = 400 - CodeUnauthorized = 401 - CodeForbidden = 403 - CodeNotFound = 404 - CodeGone = 410 - CodeInternalError = 500 + CodeSuccess = 200 + CodeBadRequest = 400 + CodeUnauthorized = 401 + CodeForbidden = 403 + CodeNotFound = 404 + CodeGone = 410 + CodeInternalError = 500 + CodeTooManyRequests = 429 ) // NewResponse 创建响应 diff --git a/main.go b/main.go index 7378701..390054f 100644 --- a/main.go +++ b/main.go @@ -69,11 +69,16 @@ func main() { api := r.Group("/api") { - api.POST("/upload", uploadHandler.Upload) - api.POST("/upload/text", uploadHandler.UploadText) - api.GET("/pickup/:pickup_code", middleware.PickupRateLimit(), pickupHandler.Pickup) - api.GET("/download/file/:file_id", pickupHandler.DownloadFile) - api.GET("/download/batch/:pickup_code", pickupHandler.DownloadBatch) + // 统一使用 /batches 作为资源路径 + api.POST("/batches", uploadHandler.Upload) + api.POST("/batches/text", uploadHandler.UploadText) + api.GET("/batches/:pickup_code", middleware.PickupRateLimit(), pickupHandler.Pickup) + api.GET("/batches/:pickup_code/download", pickupHandler.DownloadBatch) + // 文件下载保持 /files/:id/download 风格 + api.GET("/files/:file_id/download", pickupHandler.DownloadFile) + + // 保持旧路由兼容性 (可选,但为了平滑过渡通常建议保留一段时间或直接更新) + // 这里根据需求“调整不符合规范的”,我将直接采用新路由 } // 管理员接口 @@ -87,13 +92,14 @@ func main() { adm.Use(middleware.AdminAuth()) { adm.GET("/batches", batchHandler.ListBatches) - adm.GET("/batch/:batch_id", batchHandler.GetBatch) - adm.PUT("/batch/:batch_id", batchHandler.UpdateBatch) - adm.DELETE("/batch/:batch_id", batchHandler.DeleteBatch) + adm.GET("/batches/:batch_id", batchHandler.GetBatch) + adm.PUT("/batches/:batch_id", batchHandler.UpdateBatch) + adm.DELETE("/batches/:batch_id", batchHandler.DeleteBatch) adm.GET("/api-tokens", tokenHandler.ListTokens) adm.POST("/api-tokens", tokenHandler.CreateToken) adm.DELETE("/api-tokens/:id", tokenHandler.DeleteToken) + adm.POST("/api-tokens/:id/revoke", tokenHandler.RevokeToken) } // 5. 运行