实现swagger

This commit is contained in:
2025-09-12 17:43:42 +08:00
parent fe9b0db985
commit 9e9bf7b8a0
6 changed files with 745 additions and 197 deletions

View File

@@ -23,6 +23,153 @@ const docTemplate = `{
"host": "{{.Host}}", "host": "{{.Host}}",
"basePath": "{{.BasePath}}", "basePath": "{{.BasePath}}",
"paths": { "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": { "/users": {
"post": { "post": {
"description": "根据用户名和密码创建一个新的系统用户。", "description": "根据用户名和密码创建一个新的系统用户。",
@@ -49,37 +196,7 @@ const docTemplate = `{
], ],
"responses": { "responses": {
"200": { "200": {
"description": "用户创建成功", "description": "业务失败具体错误码和信息见响应体例如400, 409, 500",
"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": "服务器内部错误",
"schema": { "schema": {
"$ref": "#/definitions/controller.Response" "$ref": "#/definitions/controller.Response"
} }
@@ -113,37 +230,7 @@ const docTemplate = `{
], ],
"responses": { "responses": {
"200": { "200": {
"description": "登录成功", "description": "业务失败具体错误码和信息见响应体例如400, 401, 500",
"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": "服务器内部错误",
"schema": { "schema": {
"$ref": "#/definitions/controller.Response" "$ref": "#/definitions/controller.Response"
} }
@@ -153,6 +240,9 @@ const docTemplate = `{
} }
}, },
"definitions": { "definitions": {
"controller.Properties": {
"type": "object"
},
"controller.Response": { "controller.Response": {
"type": "object", "type": "object",
"properties": { "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": { "user.CreateUserRequest": {
"type": "object", "type": "object",
"required": [ "required": [
@@ -240,7 +424,7 @@ const docTemplate = `{
// SwaggerInfo holds exported Swagger Info so clients can modify it // SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo = &swag.Spec{ var SwaggerInfo = &swag.Spec{
Version: "1.0", Version: "1.0",
Host: "localhost:8080", Host: "localhost:8086",
BasePath: "/api/v1", BasePath: "/api/v1",
Schemes: []string{}, Schemes: []string{},
Title: "猪场管理系统 API", Title: "猪场管理系统 API",

View File

@@ -14,9 +14,156 @@
}, },
"version": "1.0" "version": "1.0"
}, },
"host": "localhost:8080", "host": "localhost:8086",
"basePath": "/api/v1", "basePath": "/api/v1",
"paths": { "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": { "/users": {
"post": { "post": {
"description": "根据用户名和密码创建一个新的系统用户。", "description": "根据用户名和密码创建一个新的系统用户。",
@@ -43,37 +190,7 @@
], ],
"responses": { "responses": {
"200": { "200": {
"description": "用户创建成功", "description": "业务失败具体错误码和信息见响应体例如400, 409, 500",
"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": "服务器内部错误",
"schema": { "schema": {
"$ref": "#/definitions/controller.Response" "$ref": "#/definitions/controller.Response"
} }
@@ -107,37 +224,7 @@
], ],
"responses": { "responses": {
"200": { "200": {
"description": "登录成功", "description": "业务失败具体错误码和信息见响应体例如400, 401, 500",
"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": "服务器内部错误",
"schema": { "schema": {
"$ref": "#/definitions/controller.Response" "$ref": "#/definitions/controller.Response"
} }
@@ -147,6 +234,9 @@
} }
}, },
"definitions": { "definitions": {
"controller.Properties": {
"type": "object"
},
"controller.Response": { "controller.Response": {
"type": "object", "type": "object",
"properties": { "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": { "user.CreateUserRequest": {
"type": "object", "type": "object",
"required": [ "required": [

View File

@@ -1,5 +1,7 @@
basePath: /api/v1 basePath: /api/v1
definitions: definitions:
controller.Properties:
type: object
controller.Response: controller.Response:
properties: properties:
code: code:
@@ -11,6 +13,73 @@ definitions:
description: 提示信息 description: 提示信息
type: string type: string
type: object 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: user.CreateUserRequest:
properties: properties:
password: password:
@@ -57,7 +126,7 @@ definitions:
example: testuser example: testuser
type: string type: string
type: object type: object
host: localhost:8080 host: localhost:8086
info: info:
contact: contact:
email: divano@example.com email: divano@example.com
@@ -70,6 +139,103 @@ info:
title: 猪场管理系统 API title: 猪场管理系统 API
version: "1.0" version: "1.0"
paths: 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: /users:
post: post:
consumes: consumes:
@@ -86,24 +252,7 @@ paths:
- application/json - application/json
responses: responses:
"200": "200":
description: 用户创建成功 description: 业务失败具体错误码和信息见响应体例如400, 409, 500
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: 服务器内部错误
schema: schema:
$ref: '#/definitions/controller.Response' $ref: '#/definitions/controller.Response'
summary: 创建新用户 summary: 创建新用户
@@ -125,24 +274,7 @@ paths:
- application/json - application/json
responses: responses:
"200": "200":
description: 登录成功 description: 业务失败具体错误码和信息见响应体例如400, 401, 500
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: 服务器内部错误
schema: schema:
$ref: '#/definitions/controller.Response' $ref: '#/definitions/controller.Response'
summary: 用户登录 summary: 用户登录

View File

@@ -5,6 +5,7 @@ import (
"net/http" "net/http"
"strconv" "strconv"
"strings" "strings"
"time"
"git.huangwc.com/pig/pig-farm-controller/internal/app/controller" "git.huangwc.com/pig/pig-farm-controller/internal/app/controller"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
@@ -29,7 +30,7 @@ func NewController(repo repository.DeviceRepository, logger *logs.Logger) *Contr
} }
} }
// --- Request & Response Structs --- // --- Request DTOs ---
// CreateDeviceRequest 定义了创建设备时需要传入的参数 // CreateDeviceRequest 定义了创建设备时需要传入的参数
type CreateDeviceRequest struct { type CreateDeviceRequest struct {
@@ -38,7 +39,7 @@ type CreateDeviceRequest struct {
SubType models.DeviceSubType `json:"sub_type,omitempty"` SubType models.DeviceSubType `json:"sub_type,omitempty"`
ParentID *uint `json:"parent_id,omitempty"` ParentID *uint `json:"parent_id,omitempty"`
Location string `json:"location,omitempty"` Location string `json:"location,omitempty"`
Properties datatypes.JSON `json:"properties,omitempty"` Properties controller.Properties `json:"properties,omitempty"`
} }
// UpdateDeviceRequest 定义了更新设备时需要传入的参数 // UpdateDeviceRequest 定义了更新设备时需要传入的参数
@@ -48,20 +49,64 @@ type UpdateDeviceRequest struct {
SubType models.DeviceSubType `json:"sub_type,omitempty"` SubType models.DeviceSubType `json:"sub_type,omitempty"`
ParentID *uint `json:"parent_id,omitempty"` ParentID *uint `json:"parent_id,omitempty"`
Location string `json:"location,omitempty"` Location string `json:"location,omitempty"`
Properties datatypes.JSON `json:"properties,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 --- // --- Controller Methods ---
// CreateDevice godoc // CreateDevice godoc
// @Summary 创建新设备 // @Summary 创建新设备
// @Description 根据提供的信息创建一个新设备,可以是区域主控或普通设备 // @Description 根据提供的信息创建一个新设备
// @Tags 设备管理 // @Tags 设备管理
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param device body CreateDeviceRequest true "设备信息" // @Param device body CreateDeviceRequest true "设备信息"
// @Success 200 {object} controller.Response{data=models.Device} "业务码为201代表创建成功" // @Success 200 {object} controller.Response{data=DeviceResponse} "业务码为201代表创建成功"
// @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体例如400, 500" // @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体"
// @Router /devices [post] // @Router /devices [post]
func (c *Controller) CreateDevice(ctx *gin.Context) { func (c *Controller) CreateDevice(ctx *gin.Context) {
var req CreateDeviceRequest var req CreateDeviceRequest
@@ -77,7 +122,7 @@ func (c *Controller) CreateDevice(ctx *gin.Context) {
SubType: req.SubType, SubType: req.SubType,
ParentID: req.ParentID, ParentID: req.ParentID,
Location: req.Location, Location: req.Location,
Properties: req.Properties, Properties: datatypes.JSON(req.Properties),
} }
if err := c.repo.Create(device); err != nil { if err := c.repo.Create(device); err != nil {
@@ -86,7 +131,7 @@ func (c *Controller) CreateDevice(ctx *gin.Context) {
return return
} }
controller.SendResponse(ctx, http.StatusCreated, "设备创建成功", device) controller.SendResponse(ctx, http.StatusCreated, "设备创建成功", newDeviceResponse(device))
} }
// GetDevice godoc // GetDevice godoc
@@ -95,8 +140,8 @@ func (c *Controller) CreateDevice(ctx *gin.Context) {
// @Tags 设备管理 // @Tags 设备管理
// @Produce json // @Produce json
// @Param id path string true "设备ID" // @Param id path string true "设备ID"
// @Success 200 {object} controller.Response{data=models.Device} "业务码为200代表获取成功" // @Success 200 {object} controller.Response{data=DeviceResponse} "业务码为200代表获取成功"
// @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体例如400, 404, 500" // @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体"
// @Router /devices/{id} [get] // @Router /devices/{id} [get]
func (c *Controller) GetDevice(ctx *gin.Context) { func (c *Controller) GetDevice(ctx *gin.Context) {
deviceID := ctx.Param("id") deviceID := ctx.Param("id")
@@ -107,7 +152,6 @@ func (c *Controller) GetDevice(ctx *gin.Context) {
controller.SendErrorResponse(ctx, http.StatusNotFound, "设备未找到") controller.SendErrorResponse(ctx, http.StatusNotFound, "设备未找到")
return return
} }
// 检查是否是ID格式错误
if strings.Contains(err.Error(), "无效的设备ID格式") { if strings.Contains(err.Error(), "无效的设备ID格式") {
controller.SendErrorResponse(ctx, http.StatusBadRequest, err.Error()) controller.SendErrorResponse(ctx, http.StatusBadRequest, err.Error())
return return
@@ -117,7 +161,7 @@ func (c *Controller) GetDevice(ctx *gin.Context) {
return return
} }
controller.SendResponse(ctx, http.StatusOK, "获取设备信息成功", device) controller.SendResponse(ctx, http.StatusOK, "获取设备信息成功", newDeviceResponse(device))
} }
// ListDevices godoc // ListDevices godoc
@@ -125,8 +169,8 @@ func (c *Controller) GetDevice(ctx *gin.Context) {
// @Description 获取系统中所有设备的列表 // @Description 获取系统中所有设备的列表
// @Tags 设备管理 // @Tags 设备管理
// @Produce json // @Produce json
// @Success 200 {object} controller.Response{data=[]models.Device} "业务码为200代表获取成功" // @Success 200 {object} controller.Response{data=[]DeviceResponse} "业务码为200代表获取成功"
// @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体例如500" // @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体"
// @Router /devices [get] // @Router /devices [get]
func (c *Controller) ListDevices(ctx *gin.Context) { func (c *Controller) ListDevices(ctx *gin.Context) {
devices, err := c.repo.ListAll() devices, err := c.repo.ListAll()
@@ -136,7 +180,7 @@ func (c *Controller) ListDevices(ctx *gin.Context) {
return return
} }
controller.SendResponse(ctx, http.StatusOK, "获取设备列表成功", devices) controller.SendResponse(ctx, http.StatusOK, "获取设备列表成功", newListDeviceResponse(devices))
} }
// UpdateDevice godoc // UpdateDevice godoc
@@ -147,8 +191,8 @@ func (c *Controller) ListDevices(ctx *gin.Context) {
// @Produce json // @Produce json
// @Param id path string true "设备ID" // @Param id path string true "设备ID"
// @Param device body UpdateDeviceRequest true "要更新的设备信息" // @Param device body UpdateDeviceRequest true "要更新的设备信息"
// @Success 200 {object} controller.Response{data=models.Device} "业务码为200代表更新成功" // @Success 200 {object} controller.Response{data=DeviceResponse} "业务码为200代表更新成功"
// @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体例如400, 404, 500" // @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体"
// @Router /devices/{id} [put] // @Router /devices/{id} [put]
func (c *Controller) UpdateDevice(ctx *gin.Context) { func (c *Controller) UpdateDevice(ctx *gin.Context) {
deviceID := ctx.Param("id") deviceID := ctx.Param("id")
@@ -183,7 +227,7 @@ func (c *Controller) UpdateDevice(ctx *gin.Context) {
existingDevice.SubType = req.SubType existingDevice.SubType = req.SubType
existingDevice.ParentID = req.ParentID existingDevice.ParentID = req.ParentID
existingDevice.Location = req.Location existingDevice.Location = req.Location
existingDevice.Properties = req.Properties existingDevice.Properties = datatypes.JSON(req.Properties)
// 4. 保存到数据库 // 4. 保存到数据库
if err := c.repo.Update(existingDevice); err != nil { if err := c.repo.Update(existingDevice); err != nil {
@@ -192,7 +236,7 @@ func (c *Controller) UpdateDevice(ctx *gin.Context) {
return return
} }
controller.SendResponse(ctx, http.StatusOK, "设备更新成功", existingDevice) controller.SendResponse(ctx, http.StatusOK, "设备更新成功", newDeviceResponse(existingDevice))
} }
// DeleteDevice godoc // DeleteDevice godoc
@@ -202,7 +246,7 @@ func (c *Controller) UpdateDevice(ctx *gin.Context) {
// @Produce json // @Produce json
// @Param id path string true "设备ID" // @Param id path string true "设备ID"
// @Success 200 {object} controller.Response "业务码为200代表删除成功" // @Success 200 {object} controller.Response "业务码为200代表删除成功"
// @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体例如400, 500" // @Failure 200 {object} controller.Response "业务失败,具体错误码和信息见响应体"
// @Router /devices/{id} [delete] // @Router /devices/{id} [delete]
func (c *Controller) DeleteDevice(ctx *gin.Context) { func (c *Controller) DeleteDevice(ctx *gin.Context) {
deviceID := ctx.Param("id") deviceID := ctx.Param("id")

View File

@@ -1,11 +1,14 @@
package controller package controller
import ( import (
"encoding/json"
"net/http" "net/http"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
// --- 通用响应结构 ---
// Response 定义统一的API响应结构体 // Response 定义统一的API响应结构体
type Response struct { type Response struct {
Code int `json:"code"` // 业务状态码 Code int `json:"code"` // 业务状态码
@@ -14,7 +17,6 @@ type Response struct {
} }
// SendResponse 发送统一格式的JSON响应 // SendResponse 发送统一格式的JSON响应
// httpStatus 参数现在将几乎总是 http.StatusOK业务状态码通过 Response.Code 传递
func SendResponse(ctx *gin.Context, code int, message string, data interface{}) { func SendResponse(ctx *gin.Context, code int, message string, data interface{}) {
ctx.JSON(http.StatusOK, Response{ ctx.JSON(http.StatusOK, Response{
Code: code, Code: code,
@@ -24,7 +26,9 @@ func SendResponse(ctx *gin.Context, code int, message string, data interface{})
} }
// SendErrorResponse 发送统一格式的错误响应 // SendErrorResponse 发送统一格式的错误响应
// 错误响应通常不包含业务数据,因此 data 参数固定为 nil
func SendErrorResponse(ctx *gin.Context, code int, message string) { func SendErrorResponse(ctx *gin.Context, code int, message string) {
SendResponse(ctx, code, message, nil) SendResponse(ctx, code, message, nil)
} }
// Properties 是一个自定义类型,用于在 Swagger 中正确表示 JSON 对象
type Properties json.RawMessage

View File

@@ -60,7 +60,7 @@ type LoginResponse struct {
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param user body CreateUserRequest true "用户信息" // @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" // @Failure 200 {object} controller.Response "业务失败具体错误码和信息见响应体例如400, 409, 500"
// @Router /users [post] // @Router /users [post]
func (c *Controller) CreateUser(ctx *gin.Context) { func (c *Controller) CreateUser(ctx *gin.Context) {
@@ -104,7 +104,7 @@ func (c *Controller) CreateUser(ctx *gin.Context) {
// @Accept json // @Accept json
// @Produce json // @Produce json
// @Param credentials body LoginRequest true "登录凭证" // @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" // @Failure 200 {object} controller.Response "业务失败具体错误码和信息见响应体例如400, 401, 500"
// @Router /users/login [post] // @Router /users/login [post]
func (c *Controller) Login(ctx *gin.Context) { func (c *Controller) Login(ctx *gin.Context) {