修复bug
This commit is contained in:
		| @@ -1,7 +1,9 @@ | ||||
| package device | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| @@ -11,7 +13,6 @@ import ( | ||||
| 	"git.huangwc.com/pig/pig-farm-controller/internal/infra/models" | ||||
| 	"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository" | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	"gorm.io/datatypes" | ||||
| 	"gorm.io/gorm" | ||||
| ) | ||||
|  | ||||
| @@ -33,46 +34,54 @@ func NewController(repo repository.DeviceRepository, logger *logs.Logger) *Contr | ||||
|  | ||||
| // 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 controller.Properties `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 map[string]interface{} `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 controller.Properties `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 map[string]interface{} `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"` | ||||
| 	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 map[string]interface{} `json:"properties"` | ||||
| 	CreatedAt  string                 `json:"created_at"` | ||||
| 	UpdatedAt  string                 `json:"updated_at"` | ||||
| } | ||||
|  | ||||
| // --- DTO 转换函数 --- | ||||
|  | ||||
| // newDeviceResponse 从数据库模型创建一个新的设备响应 DTO | ||||
| func newDeviceResponse(device *models.Device) *DeviceResponse { | ||||
| func newDeviceResponse(device *models.Device) (*DeviceResponse, error) { | ||||
| 	if device == nil { | ||||
| 		return nil | ||||
| 		return nil, nil | ||||
| 	} | ||||
|  | ||||
| 	var props map[string]interface{} | ||||
| 	if len(device.Properties) > 0 && string(device.Properties) != "null" { | ||||
| 		if err := json.Unmarshal(device.Properties, &props); err != nil { | ||||
| 			return nil, fmt.Errorf("解析设备属性失败 (ID: %d): %w", device.ID, err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return &DeviceResponse{ | ||||
| 		ID:         device.ID, | ||||
| 		Name:       device.Name, | ||||
| @@ -80,19 +89,23 @@ func newDeviceResponse(device *models.Device) *DeviceResponse { | ||||
| 		SubType:    device.SubType, | ||||
| 		ParentID:   device.ParentID, | ||||
| 		Location:   device.Location, | ||||
| 		Properties: controller.Properties(device.Properties), | ||||
| 		Properties: props, | ||||
| 		CreatedAt:  device.CreatedAt.Format(time.RFC3339), | ||||
| 		UpdatedAt:  device.UpdatedAt.Format(time.RFC3339), | ||||
| 	} | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| // newListDeviceResponse 从数据库模型切片创建一个新的设备列表响应 DTO 切片 | ||||
| func newListDeviceResponse(devices []*models.Device) []*DeviceResponse { | ||||
| func newListDeviceResponse(devices []*models.Device) ([]*DeviceResponse, error) { | ||||
| 	list := make([]*DeviceResponse, 0, len(devices)) | ||||
| 	for _, device := range devices { | ||||
| 		list = append(list, newDeviceResponse(device)) | ||||
| 		resp, err := newDeviceResponse(device) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		list = append(list, resp) | ||||
| 	} | ||||
| 	return list | ||||
| 	return list, nil | ||||
| } | ||||
|  | ||||
| // --- Controller Methods --- | ||||
| @@ -114,13 +127,20 @@ func (c *Controller) CreateDevice(ctx *gin.Context) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	propertiesJSON, err := json.Marshal(req.Properties) | ||||
| 	if err != nil { | ||||
| 		c.logger.Errorf("创建设备: 序列化属性失败: %v", err) | ||||
| 		controller.SendErrorResponse(ctx, controller.CodeBadRequest, "属性字段格式错误") | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	device := &models.Device{ | ||||
| 		Name:       req.Name, | ||||
| 		Type:       req.Type, | ||||
| 		SubType:    req.SubType, | ||||
| 		ParentID:   req.ParentID, | ||||
| 		Location:   req.Location, | ||||
| 		Properties: datatypes.JSON(req.Properties), | ||||
| 		Properties: propertiesJSON, | ||||
| 	} | ||||
|  | ||||
| 	if err := c.repo.Create(device); err != nil { | ||||
| @@ -129,7 +149,14 @@ func (c *Controller) CreateDevice(ctx *gin.Context) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	controller.SendResponse(ctx, controller.CodeCreated, "设备创建成功", newDeviceResponse(device)) | ||||
| 	resp, err := newDeviceResponse(device) | ||||
| 	if err != nil { | ||||
| 		c.logger.Errorf("创建设备: 序列化响应失败: %v", err) | ||||
| 		controller.SendErrorResponse(ctx, controller.CodeInternalError, "设备创建成功,但响应生成失败") | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	controller.SendResponse(ctx, controller.CodeCreated, "设备创建成功", resp) | ||||
| } | ||||
|  | ||||
| // GetDevice godoc | ||||
| @@ -158,7 +185,14 @@ func (c *Controller) GetDevice(ctx *gin.Context) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	controller.SendResponse(ctx, controller.CodeSuccess, "获取设备信息成功", newDeviceResponse(device)) | ||||
| 	resp, err := newDeviceResponse(device) | ||||
| 	if err != nil { | ||||
| 		c.logger.Errorf("获取设备: 序列化响应失败: %v", err) | ||||
| 		controller.SendErrorResponse(ctx, controller.CodeInternalError, "获取设备信息失败: 内部数据格式错误") | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	controller.SendResponse(ctx, controller.CodeSuccess, "获取设备信息成功", resp) | ||||
| } | ||||
|  | ||||
| // ListDevices godoc | ||||
| @@ -176,7 +210,14 @@ func (c *Controller) ListDevices(ctx *gin.Context) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	controller.SendResponse(ctx, controller.CodeSuccess, "获取设备列表成功", newListDeviceResponse(devices)) | ||||
| 	resp, err := newListDeviceResponse(devices) | ||||
| 	if err != nil { | ||||
| 		c.logger.Errorf("获取设备列表: 序列化响应失败: %v", err) | ||||
| 		controller.SendErrorResponse(ctx, controller.CodeInternalError, "获取设备列表失败: 内部数据格式错误") | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	controller.SendResponse(ctx, controller.CodeSuccess, "获取设备列表成功", resp) | ||||
| } | ||||
|  | ||||
| // UpdateDevice godoc | ||||
| @@ -216,13 +257,20 @@ func (c *Controller) UpdateDevice(ctx *gin.Context) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	propertiesJSON, err := json.Marshal(req.Properties) | ||||
| 	if err != nil { | ||||
| 		c.logger.Errorf("更新设备: 序列化属性失败: %v", err) | ||||
| 		controller.SendErrorResponse(ctx, controller.CodeBadRequest, "属性字段格式错误") | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	// 3. 更新从数据库中查出的现有设备对象的字段 | ||||
| 	existingDevice.Name = req.Name | ||||
| 	existingDevice.Type = req.Type | ||||
| 	existingDevice.SubType = req.SubType | ||||
| 	existingDevice.ParentID = req.ParentID | ||||
| 	existingDevice.Location = req.Location | ||||
| 	existingDevice.Properties = datatypes.JSON(req.Properties) | ||||
| 	existingDevice.Properties = propertiesJSON | ||||
|  | ||||
| 	// 4. 将修改后的 existingDevice 对象保存回数据库 | ||||
| 	if err := c.repo.Update(existingDevice); err != nil { | ||||
| @@ -231,7 +279,14 @@ func (c *Controller) UpdateDevice(ctx *gin.Context) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	controller.SendResponse(ctx, controller.CodeSuccess, "设备更新成功", newDeviceResponse(existingDevice)) | ||||
| 	resp, err := newDeviceResponse(existingDevice) | ||||
| 	if err != nil { | ||||
| 		c.logger.Errorf("更新设备: 序列化响应失败: %v", err) | ||||
| 		controller.SendErrorResponse(ctx, controller.CodeInternalError, "设备更新成功,但响应生成失败") | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	controller.SendResponse(ctx, controller.CodeSuccess, "设备更新成功", resp) | ||||
| } | ||||
|  | ||||
| // DeleteDevice godoc | ||||
|   | ||||
		Reference in New Issue
	
	Block a user