From 9e9bf7b8a0ee28a43de76d489a8c151904a71d1b Mon Sep 17 00:00:00 2001 From: huang <1724659546@qq.com> Date: Fri, 12 Sep 2025 17:43:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0swagger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/docs.go | 310 ++++++++++++++---- docs/swagger.json | 310 ++++++++++++++---- docs/swagger.yaml | 206 +++++++++--- .../controller/device/device_controller.go | 104 ++++-- internal/app/controller/response.go | 8 +- .../app/controller/user/user_controller.go | 4 +- 6 files changed, 745 insertions(+), 197 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index 2869c04..beb23bf 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -23,6 +23,153 @@ const docTemplate = `{ "host": "{{.Host}}", "basePath": "{{.BasePath}}", "paths": { + "/devices": { + "get": { + "description": "获取系统中所有设备的列表", + "produces": [ + "application/json" + ], + "tags": [ + "设备管理" + ], + "summary": "获取设备列表", + "responses": { + "200": { + "description": "业务失败,具体错误码和信息见响应体", + "schema": { + "$ref": "#/definitions/controller.Response" + } + } + } + }, + "post": { + "description": "根据提供的信息创建一个新设备", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "设备管理" + ], + "summary": "创建新设备", + "parameters": [ + { + "description": "设备信息", + "name": "device", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/device.CreateDeviceRequest" + } + } + ], + "responses": { + "200": { + "description": "业务失败,具体错误码和信息见响应体", + "schema": { + "$ref": "#/definitions/controller.Response" + } + } + } + } + }, + "/devices/{id}": { + "get": { + "description": "根据设备ID获取单个设备的详细信息", + "produces": [ + "application/json" + ], + "tags": [ + "设备管理" + ], + "summary": "获取设备信息", + "parameters": [ + { + "type": "string", + "description": "设备ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "业务失败,具体错误码和信息见响应体", + "schema": { + "$ref": "#/definitions/controller.Response" + } + } + } + }, + "put": { + "description": "根据设备ID更新一个已存在的设备信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "设备管理" + ], + "summary": "更新设备信息", + "parameters": [ + { + "type": "string", + "description": "设备ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "要更新的设备信息", + "name": "device", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/device.UpdateDeviceRequest" + } + } + ], + "responses": { + "200": { + "description": "业务失败,具体错误码和信息见响应体", + "schema": { + "$ref": "#/definitions/controller.Response" + } + } + } + }, + "delete": { + "description": "根据设备ID删除一个设备(软删除)", + "produces": [ + "application/json" + ], + "tags": [ + "设备管理" + ], + "summary": "删除设备", + "parameters": [ + { + "type": "string", + "description": "设备ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "业务失败,具体错误码和信息见响应体", + "schema": { + "$ref": "#/definitions/controller.Response" + } + } + } + } + }, "/users": { "post": { "description": "根据用户名和密码创建一个新的系统用户。", @@ -49,37 +196,7 @@ const docTemplate = `{ ], "responses": { "200": { - "description": "用户创建成功", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/controller.Response" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/user.CreateUserResponse" - } - } - } - ] - } - }, - "400": { - "description": "请求参数错误", - "schema": { - "$ref": "#/definitions/controller.Response" - } - }, - "409": { - "description": "用户名已存在", - "schema": { - "$ref": "#/definitions/controller.Response" - } - }, - "500": { - "description": "服务器内部错误", + "description": "业务失败,具体错误码和信息见响应体(例如400, 409, 500)", "schema": { "$ref": "#/definitions/controller.Response" } @@ -113,37 +230,7 @@ const docTemplate = `{ ], "responses": { "200": { - "description": "登录成功", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/controller.Response" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/user.LoginResponse" - } - } - } - ] - } - }, - "400": { - "description": "请求参数错误", - "schema": { - "$ref": "#/definitions/controller.Response" - } - }, - "401": { - "description": "用户名或密码不正确", - "schema": { - "$ref": "#/definitions/controller.Response" - } - }, - "500": { - "description": "服务器内部错误", + "description": "业务失败,具体错误码和信息见响应体(例如400, 401, 500)", "schema": { "$ref": "#/definitions/controller.Response" } @@ -153,6 +240,9 @@ const docTemplate = `{ } }, "definitions": { + "controller.Properties": { + "type": "object" + }, "controller.Response": { "type": "object", "properties": { @@ -169,6 +259,100 @@ const docTemplate = `{ } } }, + "device.CreateDeviceRequest": { + "type": "object" + }, + "device.DeviceResponse": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "location": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parent_id": { + "type": "integer" + }, + "properties": { + "$ref": "#/definitions/controller.Properties" + }, + "sub_type": { + "$ref": "#/definitions/models.DeviceSubType" + }, + "type": { + "$ref": "#/definitions/models.DeviceType" + }, + "updated_at": { + "type": "string" + } + } + }, + "device.UpdateDeviceRequest": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "location": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parent_id": { + "type": "integer" + }, + "properties": { + "$ref": "#/definitions/controller.Properties" + }, + "sub_type": { + "$ref": "#/definitions/models.DeviceSubType" + }, + "type": { + "$ref": "#/definitions/models.DeviceType" + } + } + }, + "models.DeviceSubType": { + "type": "string", + "enum": [ + "", + "temperature", + "humidity", + "ammonia", + "feed_valve", + "fan", + "water_curtain" + ], + "x-enum-varnames": [ + "SubTypeNone", + "SubTypeSensorTemp", + "SubTypeSensorHumidity", + "SubTypeSensorAmmonia", + "SubTypeValveFeed", + "SubTypeFan", + "SubTypeWaterCurtain" + ] + }, + "models.DeviceType": { + "type": "string", + "enum": [ + "area_controller", + "device" + ], + "x-enum-varnames": [ + "DeviceTypeAreaController", + "DeviceTypeDevice" + ] + }, "user.CreateUserRequest": { "type": "object", "required": [ @@ -240,7 +424,7 @@ const docTemplate = `{ // SwaggerInfo holds exported Swagger Info so clients can modify it var SwaggerInfo = &swag.Spec{ Version: "1.0", - Host: "localhost:8080", + Host: "localhost:8086", BasePath: "/api/v1", Schemes: []string{}, Title: "猪场管理系统 API", diff --git a/docs/swagger.json b/docs/swagger.json index 0d8e334..f1aa166 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -14,9 +14,156 @@ }, "version": "1.0" }, - "host": "localhost:8080", + "host": "localhost:8086", "basePath": "/api/v1", "paths": { + "/devices": { + "get": { + "description": "获取系统中所有设备的列表", + "produces": [ + "application/json" + ], + "tags": [ + "设备管理" + ], + "summary": "获取设备列表", + "responses": { + "200": { + "description": "业务失败,具体错误码和信息见响应体", + "schema": { + "$ref": "#/definitions/controller.Response" + } + } + } + }, + "post": { + "description": "根据提供的信息创建一个新设备", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "设备管理" + ], + "summary": "创建新设备", + "parameters": [ + { + "description": "设备信息", + "name": "device", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/device.CreateDeviceRequest" + } + } + ], + "responses": { + "200": { + "description": "业务失败,具体错误码和信息见响应体", + "schema": { + "$ref": "#/definitions/controller.Response" + } + } + } + } + }, + "/devices/{id}": { + "get": { + "description": "根据设备ID获取单个设备的详细信息", + "produces": [ + "application/json" + ], + "tags": [ + "设备管理" + ], + "summary": "获取设备信息", + "parameters": [ + { + "type": "string", + "description": "设备ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "业务失败,具体错误码和信息见响应体", + "schema": { + "$ref": "#/definitions/controller.Response" + } + } + } + }, + "put": { + "description": "根据设备ID更新一个已存在的设备信息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "设备管理" + ], + "summary": "更新设备信息", + "parameters": [ + { + "type": "string", + "description": "设备ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "要更新的设备信息", + "name": "device", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/device.UpdateDeviceRequest" + } + } + ], + "responses": { + "200": { + "description": "业务失败,具体错误码和信息见响应体", + "schema": { + "$ref": "#/definitions/controller.Response" + } + } + } + }, + "delete": { + "description": "根据设备ID删除一个设备(软删除)", + "produces": [ + "application/json" + ], + "tags": [ + "设备管理" + ], + "summary": "删除设备", + "parameters": [ + { + "type": "string", + "description": "设备ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "业务失败,具体错误码和信息见响应体", + "schema": { + "$ref": "#/definitions/controller.Response" + } + } + } + } + }, "/users": { "post": { "description": "根据用户名和密码创建一个新的系统用户。", @@ -43,37 +190,7 @@ ], "responses": { "200": { - "description": "用户创建成功", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/controller.Response" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/user.CreateUserResponse" - } - } - } - ] - } - }, - "400": { - "description": "请求参数错误", - "schema": { - "$ref": "#/definitions/controller.Response" - } - }, - "409": { - "description": "用户名已存在", - "schema": { - "$ref": "#/definitions/controller.Response" - } - }, - "500": { - "description": "服务器内部错误", + "description": "业务失败,具体错误码和信息见响应体(例如400, 409, 500)", "schema": { "$ref": "#/definitions/controller.Response" } @@ -107,37 +224,7 @@ ], "responses": { "200": { - "description": "登录成功", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/controller.Response" - }, - { - "type": "object", - "properties": { - "data": { - "$ref": "#/definitions/user.LoginResponse" - } - } - } - ] - } - }, - "400": { - "description": "请求参数错误", - "schema": { - "$ref": "#/definitions/controller.Response" - } - }, - "401": { - "description": "用户名或密码不正确", - "schema": { - "$ref": "#/definitions/controller.Response" - } - }, - "500": { - "description": "服务器内部错误", + "description": "业务失败,具体错误码和信息见响应体(例如400, 401, 500)", "schema": { "$ref": "#/definitions/controller.Response" } @@ -147,6 +234,9 @@ } }, "definitions": { + "controller.Properties": { + "type": "object" + }, "controller.Response": { "type": "object", "properties": { @@ -163,6 +253,100 @@ } } }, + "device.CreateDeviceRequest": { + "type": "object" + }, + "device.DeviceResponse": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "location": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parent_id": { + "type": "integer" + }, + "properties": { + "$ref": "#/definitions/controller.Properties" + }, + "sub_type": { + "$ref": "#/definitions/models.DeviceSubType" + }, + "type": { + "$ref": "#/definitions/models.DeviceType" + }, + "updated_at": { + "type": "string" + } + } + }, + "device.UpdateDeviceRequest": { + "type": "object", + "required": [ + "name", + "type" + ], + "properties": { + "location": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parent_id": { + "type": "integer" + }, + "properties": { + "$ref": "#/definitions/controller.Properties" + }, + "sub_type": { + "$ref": "#/definitions/models.DeviceSubType" + }, + "type": { + "$ref": "#/definitions/models.DeviceType" + } + } + }, + "models.DeviceSubType": { + "type": "string", + "enum": [ + "", + "temperature", + "humidity", + "ammonia", + "feed_valve", + "fan", + "water_curtain" + ], + "x-enum-varnames": [ + "SubTypeNone", + "SubTypeSensorTemp", + "SubTypeSensorHumidity", + "SubTypeSensorAmmonia", + "SubTypeValveFeed", + "SubTypeFan", + "SubTypeWaterCurtain" + ] + }, + "models.DeviceType": { + "type": "string", + "enum": [ + "area_controller", + "device" + ], + "x-enum-varnames": [ + "DeviceTypeAreaController", + "DeviceTypeDevice" + ] + }, "user.CreateUserRequest": { "type": "object", "required": [ diff --git a/docs/swagger.yaml b/docs/swagger.yaml index afc0c5e..f0cd515 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1,5 +1,7 @@ basePath: /api/v1 definitions: + controller.Properties: + type: object controller.Response: properties: code: @@ -11,6 +13,73 @@ definitions: description: 提示信息 type: string type: object + device.CreateDeviceRequest: + type: object + device.DeviceResponse: + properties: + created_at: + type: string + id: + type: integer + location: + type: string + name: + type: string + parent_id: + type: integer + properties: + $ref: '#/definitions/controller.Properties' + sub_type: + $ref: '#/definitions/models.DeviceSubType' + type: + $ref: '#/definitions/models.DeviceType' + updated_at: + type: string + type: object + device.UpdateDeviceRequest: + properties: + location: + type: string + name: + type: string + parent_id: + type: integer + properties: + $ref: '#/definitions/controller.Properties' + sub_type: + $ref: '#/definitions/models.DeviceSubType' + type: + $ref: '#/definitions/models.DeviceType' + required: + - name + - type + type: object + models.DeviceSubType: + enum: + - "" + - temperature + - humidity + - ammonia + - feed_valve + - fan + - water_curtain + type: string + x-enum-varnames: + - SubTypeNone + - SubTypeSensorTemp + - SubTypeSensorHumidity + - SubTypeSensorAmmonia + - SubTypeValveFeed + - SubTypeFan + - SubTypeWaterCurtain + models.DeviceType: + enum: + - area_controller + - device + type: string + x-enum-varnames: + - DeviceTypeAreaController + - DeviceTypeDevice user.CreateUserRequest: properties: password: @@ -57,7 +126,7 @@ definitions: example: testuser type: string type: object -host: localhost:8080 +host: localhost:8086 info: contact: email: divano@example.com @@ -70,6 +139,103 @@ info: title: 猪场管理系统 API version: "1.0" paths: + /devices: + get: + description: 获取系统中所有设备的列表 + produces: + - application/json + responses: + "200": + description: 业务失败,具体错误码和信息见响应体 + schema: + $ref: '#/definitions/controller.Response' + summary: 获取设备列表 + tags: + - 设备管理 + post: + consumes: + - application/json + description: 根据提供的信息创建一个新设备 + parameters: + - description: 设备信息 + in: body + name: device + required: true + schema: + $ref: '#/definitions/device.CreateDeviceRequest' + produces: + - application/json + responses: + "200": + description: 业务失败,具体错误码和信息见响应体 + schema: + $ref: '#/definitions/controller.Response' + summary: 创建新设备 + tags: + - 设备管理 + /devices/{id}: + delete: + description: 根据设备ID删除一个设备(软删除) + parameters: + - description: 设备ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: 业务失败,具体错误码和信息见响应体 + schema: + $ref: '#/definitions/controller.Response' + summary: 删除设备 + tags: + - 设备管理 + get: + description: 根据设备ID获取单个设备的详细信息 + parameters: + - description: 设备ID + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: 业务失败,具体错误码和信息见响应体 + schema: + $ref: '#/definitions/controller.Response' + summary: 获取设备信息 + tags: + - 设备管理 + put: + consumes: + - application/json + description: 根据设备ID更新一个已存在的设备信息 + parameters: + - description: 设备ID + in: path + name: id + required: true + type: string + - description: 要更新的设备信息 + in: body + name: device + required: true + schema: + $ref: '#/definitions/device.UpdateDeviceRequest' + produces: + - application/json + responses: + "200": + description: 业务失败,具体错误码和信息见响应体 + schema: + $ref: '#/definitions/controller.Response' + summary: 更新设备信息 + tags: + - 设备管理 /users: post: consumes: @@ -86,24 +252,7 @@ paths: - application/json responses: "200": - description: 用户创建成功 - schema: - allOf: - - $ref: '#/definitions/controller.Response' - - properties: - data: - $ref: '#/definitions/user.CreateUserResponse' - type: object - "400": - description: 请求参数错误 - schema: - $ref: '#/definitions/controller.Response' - "409": - description: 用户名已存在 - schema: - $ref: '#/definitions/controller.Response' - "500": - description: 服务器内部错误 + description: 业务失败,具体错误码和信息见响应体(例如400, 409, 500) schema: $ref: '#/definitions/controller.Response' summary: 创建新用户 @@ -125,24 +274,7 @@ paths: - application/json responses: "200": - description: 登录成功 - schema: - allOf: - - $ref: '#/definitions/controller.Response' - - properties: - data: - $ref: '#/definitions/user.LoginResponse' - type: object - "400": - description: 请求参数错误 - schema: - $ref: '#/definitions/controller.Response' - "401": - description: 用户名或密码不正确 - schema: - $ref: '#/definitions/controller.Response' - "500": - description: 服务器内部错误 + description: 业务失败,具体错误码和信息见响应体(例如400, 401, 500) schema: $ref: '#/definitions/controller.Response' summary: 用户登录 diff --git a/internal/app/controller/device/device_controller.go b/internal/app/controller/device/device_controller.go index 0b3bc9c..8db26bb 100644 --- a/internal/app/controller/device/device_controller.go +++ b/internal/app/controller/device/device_controller.go @@ -5,6 +5,7 @@ import ( "net/http" "strconv" "strings" + "time" "git.huangwc.com/pig/pig-farm-controller/internal/app/controller" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" @@ -29,39 +30,83 @@ func NewController(repo repository.DeviceRepository, logger *logs.Logger) *Contr } } -// --- Request & Response Structs --- +// --- Request DTOs --- // CreateDeviceRequest 定义了创建设备时需要传入的参数 type CreateDeviceRequest struct { - Name string `json:"name" binding:"required"` - Type models.DeviceType `json:"type" binding:"required"` - SubType models.DeviceSubType `json:"sub_type,omitempty"` - ParentID *uint `json:"parent_id,omitempty"` - Location string `json:"location,omitempty"` - Properties datatypes.JSON `json:"properties,omitempty"` + Name string `json:"name" binding:"required"` + Type models.DeviceType `json:"type" binding:"required"` + SubType models.DeviceSubType `json:"sub_type,omitempty"` + ParentID *uint `json:"parent_id,omitempty"` + Location string `json:"location,omitempty"` + Properties controller.Properties `json:"properties,omitempty"` } // UpdateDeviceRequest 定义了更新设备时需要传入的参数 type UpdateDeviceRequest struct { - Name string `json:"name" binding:"required"` - Type models.DeviceType `json:"type" binding:"required"` - SubType models.DeviceSubType `json:"sub_type,omitempty"` - ParentID *uint `json:"parent_id,omitempty"` - Location string `json:"location,omitempty"` - Properties datatypes.JSON `json:"properties,omitempty"` + Name string `json:"name" binding:"required"` + Type models.DeviceType `json:"type" binding:"required"` + SubType models.DeviceSubType `json:"sub_type,omitempty"` + ParentID *uint `json:"parent_id,omitempty"` + Location string `json:"location,omitempty"` + Properties controller.Properties `json:"properties,omitempty"` +} + +// --- Response DTOs --- + +// DeviceResponse 定义了返回给客户端的单个设备信息的结构 +type DeviceResponse struct { + ID uint `json:"id"` + Name string `json:"name"` + Type models.DeviceType `json:"type"` + SubType models.DeviceSubType `json:"sub_type"` + ParentID *uint `json:"parent_id"` + Location string `json:"location"` + Properties controller.Properties `json:"properties"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` +} + +// --- DTO 转换函数 --- + +// newDeviceResponse 从数据库模型创建一个新的设备响应 DTO +func newDeviceResponse(device *models.Device) *DeviceResponse { + if device == nil { + return nil + } + return &DeviceResponse{ + ID: device.ID, + Name: device.Name, + Type: device.Type, + SubType: device.SubType, + ParentID: device.ParentID, + Location: device.Location, + Properties: controller.Properties(device.Properties), + CreatedAt: device.CreatedAt.Format(time.RFC3339), + UpdatedAt: device.UpdatedAt.Format(time.RFC3339), + } +} + +// newListDeviceResponse 从数据库模型切片创建一个新的设备列表响应 DTO 切片 +func newListDeviceResponse(devices []*models.Device) []*DeviceResponse { + list := make([]*DeviceResponse, 0, len(devices)) + for _, device := range devices { + list = append(list, newDeviceResponse(device)) + } + return list } // --- Controller Methods --- // CreateDevice godoc // @Summary 创建新设备 -// @Description 根据提供的信息创建一个新设备,可以是区域主控或普通设备 +// @Description 根据提供的信息创建一个新设备 // @Tags 设备管理 // @Accept json // @Produce json // @Param device body CreateDeviceRequest true "设备信息" -// @Success 200 {object} controller.Response{data=models.Device} "业务码为201代表创建成功" -// @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体(例如400, 500)" +// @Success 200 {object} controller.Response{data=DeviceResponse} "业务码为201代表创建成功" +// @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体" // @Router /devices [post] func (c *Controller) CreateDevice(ctx *gin.Context) { var req CreateDeviceRequest @@ -77,7 +122,7 @@ func (c *Controller) CreateDevice(ctx *gin.Context) { SubType: req.SubType, ParentID: req.ParentID, Location: req.Location, - Properties: req.Properties, + Properties: datatypes.JSON(req.Properties), } if err := c.repo.Create(device); err != nil { @@ -86,7 +131,7 @@ func (c *Controller) CreateDevice(ctx *gin.Context) { return } - controller.SendResponse(ctx, http.StatusCreated, "设备创建成功", device) + controller.SendResponse(ctx, http.StatusCreated, "设备创建成功", newDeviceResponse(device)) } // GetDevice godoc @@ -95,8 +140,8 @@ func (c *Controller) CreateDevice(ctx *gin.Context) { // @Tags 设备管理 // @Produce json // @Param id path string true "设备ID" -// @Success 200 {object} controller.Response{data=models.Device} "业务码为200代表获取成功" -// @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体(例如400, 404, 500)" +// @Success 200 {object} controller.Response{data=DeviceResponse} "业务码为200代表获取成功" +// @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体" // @Router /devices/{id} [get] func (c *Controller) GetDevice(ctx *gin.Context) { deviceID := ctx.Param("id") @@ -107,7 +152,6 @@ func (c *Controller) GetDevice(ctx *gin.Context) { controller.SendErrorResponse(ctx, http.StatusNotFound, "设备未找到") return } - // 检查是否是ID格式错误 if strings.Contains(err.Error(), "无效的设备ID格式") { controller.SendErrorResponse(ctx, http.StatusBadRequest, err.Error()) return @@ -117,7 +161,7 @@ func (c *Controller) GetDevice(ctx *gin.Context) { return } - controller.SendResponse(ctx, http.StatusOK, "获取设备信息成功", device) + controller.SendResponse(ctx, http.StatusOK, "获取设备信息成功", newDeviceResponse(device)) } // ListDevices godoc @@ -125,8 +169,8 @@ func (c *Controller) GetDevice(ctx *gin.Context) { // @Description 获取系统中所有设备的列表 // @Tags 设备管理 // @Produce json -// @Success 200 {object} controller.Response{data=[]models.Device} "业务码为200代表获取成功" -// @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体(例如500)" +// @Success 200 {object} controller.Response{data=[]DeviceResponse} "业务码为200代表获取成功" +// @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体" // @Router /devices [get] func (c *Controller) ListDevices(ctx *gin.Context) { devices, err := c.repo.ListAll() @@ -136,7 +180,7 @@ func (c *Controller) ListDevices(ctx *gin.Context) { return } - controller.SendResponse(ctx, http.StatusOK, "获取设备列表成功", devices) + controller.SendResponse(ctx, http.StatusOK, "获取设备列表成功", newListDeviceResponse(devices)) } // UpdateDevice godoc @@ -147,8 +191,8 @@ func (c *Controller) ListDevices(ctx *gin.Context) { // @Produce json // @Param id path string true "设备ID" // @Param device body UpdateDeviceRequest true "要更新的设备信息" -// @Success 200 {object} controller.Response{data=models.Device} "业务码为200代表更新成功" -// @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体(例如400, 404, 500)" +// @Success 200 {object} controller.Response{data=DeviceResponse} "业务码为200代表更新成功" +// @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体" // @Router /devices/{id} [put] func (c *Controller) UpdateDevice(ctx *gin.Context) { deviceID := ctx.Param("id") @@ -183,7 +227,7 @@ func (c *Controller) UpdateDevice(ctx *gin.Context) { existingDevice.SubType = req.SubType existingDevice.ParentID = req.ParentID existingDevice.Location = req.Location - existingDevice.Properties = req.Properties + existingDevice.Properties = datatypes.JSON(req.Properties) // 4. 保存到数据库 if err := c.repo.Update(existingDevice); err != nil { @@ -192,7 +236,7 @@ func (c *Controller) UpdateDevice(ctx *gin.Context) { return } - controller.SendResponse(ctx, http.StatusOK, "设备更新成功", existingDevice) + controller.SendResponse(ctx, http.StatusOK, "设备更新成功", newDeviceResponse(existingDevice)) } // DeleteDevice godoc @@ -202,7 +246,7 @@ func (c *Controller) UpdateDevice(ctx *gin.Context) { // @Produce json // @Param id path string true "设备ID" // @Success 200 {object} controller.Response "业务码为200代表删除成功" -// @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体(例如400, 500)" +// @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体" // @Router /devices/{id} [delete] func (c *Controller) DeleteDevice(ctx *gin.Context) { deviceID := ctx.Param("id") diff --git a/internal/app/controller/response.go b/internal/app/controller/response.go index 16aafa8..e290fa8 100644 --- a/internal/app/controller/response.go +++ b/internal/app/controller/response.go @@ -1,11 +1,14 @@ package controller import ( + "encoding/json" "net/http" "github.com/gin-gonic/gin" ) +// --- 通用响应结构 --- + // Response 定义统一的API响应结构体 type Response struct { Code int `json:"code"` // 业务状态码 @@ -14,7 +17,6 @@ type Response struct { } // SendResponse 发送统一格式的JSON响应 -// httpStatus 参数现在将几乎总是 http.StatusOK,业务状态码通过 Response.Code 传递 func SendResponse(ctx *gin.Context, code int, message string, data interface{}) { ctx.JSON(http.StatusOK, Response{ Code: code, @@ -24,7 +26,9 @@ func SendResponse(ctx *gin.Context, code int, message string, data interface{}) } // SendErrorResponse 发送统一格式的错误响应 -// 错误响应通常不包含业务数据,因此 data 参数固定为 nil func SendErrorResponse(ctx *gin.Context, code int, message string) { SendResponse(ctx, code, message, nil) } + +// Properties 是一个自定义类型,用于在 Swagger 中正确表示 JSON 对象 +type Properties json.RawMessage diff --git a/internal/app/controller/user/user_controller.go b/internal/app/controller/user/user_controller.go index b4031c5..b6cc9a9 100644 --- a/internal/app/controller/user/user_controller.go +++ b/internal/app/controller/user/user_controller.go @@ -60,7 +60,7 @@ type LoginResponse struct { // @Accept json // @Produce json // @Param user body CreateUserRequest true "用户信息" -// @Success 200 {object} controller.Response{data=CreateUserResponse} "业务码为201代表创建成功" +// @Success 200 {object} controller.Response{data=user.CreateUserResponse} "业务码为201代表创建成功" // @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体(例如400, 409, 500)" // @Router /users [post] func (c *Controller) CreateUser(ctx *gin.Context) { @@ -104,7 +104,7 @@ func (c *Controller) CreateUser(ctx *gin.Context) { // @Accept json // @Produce json // @Param credentials body LoginRequest true "登录凭证" -// @Success 200 {object} controller.Response{data=LoginResponse} "业务码为200代表登录成功" +// @Success 200 {object} controller.Response{data=user.LoginResponse} "业务码为200代表登录成功" // @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体(例如400, 401, 500)" // @Router /users/login [post] func (c *Controller) Login(ctx *gin.Context) {