issue_25 #26
@@ -35,9 +35,8 @@ 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"`
|
||||
DeviceTemplateID uint `json:"device_template_id" binding:"required"`
|
||||
AreaControllerID uint `json:"area_controller_id" binding:"required"`
|
||||
Location string `json:"location,omitempty"`
|
||||
Properties map[string]interface{} `json:"properties,omitempty"`
|
||||
}
|
||||
@@ -45,9 +44,8 @@ type CreateDeviceRequest struct {
|
||||
// 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"`
|
||||
DeviceTemplateID uint `json:"device_template_id" binding:"required"`
|
||||
AreaControllerID uint `json:"area_controller_id" binding:"required"`
|
||||
Location string `json:"location,omitempty"`
|
||||
Properties map[string]interface{} `json:"properties,omitempty"`
|
||||
}
|
||||
@@ -58,9 +56,10 @@ type UpdateDeviceRequest struct {
|
||||
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"`
|
||||
DeviceTemplateID uint `json:"device_template_id"`
|
||||
DeviceTemplateName string `json:"device_template_name"`
|
||||
AreaControllerID uint `json:"area_controller_id"`
|
||||
AreaControllerName string `json:"area_controller_name"`
|
||||
Location string `json:"location"`
|
||||
Properties map[string]interface{} `json:"properties"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
@@ -82,12 +81,24 @@ func newDeviceResponse(device *models.Device) (*DeviceResponse, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// 确保 DeviceTemplate 和 AreaController 已预加载
|
||||
deviceTemplateName := ""
|
||||
if device.DeviceTemplate.ID != 0 {
|
||||
deviceTemplateName = device.DeviceTemplate.Name
|
||||
}
|
||||
|
||||
areaControllerName := ""
|
||||
if device.AreaController.ID != 0 {
|
||||
areaControllerName = device.AreaController.Name
|
||||
}
|
||||
|
||||
return &DeviceResponse{
|
||||
ID: device.ID,
|
||||
Name: device.Name,
|
||||
Type: device.Type,
|
||||
SubType: device.SubType,
|
||||
ParentID: device.ParentID,
|
||||
DeviceTemplateID: device.DeviceTemplateID,
|
||||
DeviceTemplateName: deviceTemplateName,
|
||||
AreaControllerID: device.AreaControllerID,
|
||||
AreaControllerName: areaControllerName,
|
||||
Location: device.Location,
|
||||
Properties: props,
|
||||
CreatedAt: device.CreatedAt.Format(time.RFC3339),
|
||||
@@ -137,17 +148,20 @@ func (c *Controller) CreateDevice(ctx *gin.Context) {
|
||||
|
||||
device := &models.Device{
|
||||
Name: req.Name,
|
||||
Type: req.Type,
|
||||
SubType: req.SubType,
|
||||
ParentID: req.ParentID,
|
||||
DeviceTemplateID: req.DeviceTemplateID,
|
||||
AreaControllerID: req.AreaControllerID,
|
||||
Location: req.Location,
|
||||
Properties: propertiesJSON,
|
||||
}
|
||||
|
||||
// 在创建设备前进行自检
|
||||
if !device.SelfCheck() {
|
||||
c.logger.Errorf("%s: 设备属性自检失败: %v", actionType, device)
|
||||
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "设备属性不符合要求", actionType, "设备属性自检失败", device)
|
||||
// 注意:这里的 SelfCheck 依赖于 DeviceTemplate 和 AreaController 字段,
|
||||
// 但在创建时这些关联对象可能尚未完全加载。如果 SelfCheck 内部需要这些关联对象,
|
||||
// 则需要在调用 SelfCheck 之前手动加载或调整 SelfCheck 逻辑。
|
||||
// 目前假设 SelfCheck 仅检查 ID 和 Properties。
|
||||
if err := device.SelfCheck(); err != nil {
|
||||
c.logger.Errorf("%s: 设备属性自检失败: %v", actionType, err)
|
||||
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "设备属性不符合要求: "+err.Error(), actionType, "设备属性自检失败", device)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -157,10 +171,18 @@ func (c *Controller) CreateDevice(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := newDeviceResponse(device)
|
||||
// 为了在响应中包含 DeviceTemplateName 和 AreaControllerName,需要重新从数据库加载设备,并预加载关联。
|
||||
createdDevice, err := c.repo.FindByID(device.ID)
|
||||
if err != nil {
|
||||
c.logger.Errorf("%s: 重新加载创建的设备失败: %v", actionType, err)
|
||||
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "设备创建成功,但重新加载设备失败", actionType, "重新加载设备失败", device)
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := newDeviceResponse(createdDevice)
|
||||
if err != nil {
|
||||
c.logger.Errorf("%s: 序列化响应失败: %v", actionType, err)
|
||||
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "设备创建成功,但响应生成失败", actionType, "响应序列化失败", device)
|
||||
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "设备创建成功,但响应生成失败", actionType, "响应序列化失败", createdDevice)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -186,6 +208,7 @@ func (c *Controller) GetDevice(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 假设 FindByIDString 方法会预加载 DeviceTemplate 和 AreaController
|
||||
device, err := c.repo.FindByIDString(deviceID)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
@@ -223,6 +246,7 @@ func (c *Controller) GetDevice(ctx *gin.Context) {
|
||||
// @Router /api/v1/devices [get]
|
||||
func (c *Controller) ListDevices(ctx *gin.Context) {
|
||||
const actionType = "获取设备列表"
|
||||
// 假设 ListAll 方法会预加载 DeviceTemplate 和 AreaController
|
||||
devices, err := c.repo.ListAll()
|
||||
if err != nil {
|
||||
c.logger.Errorf("%s: 数据库查询失败: %v", actionType, err)
|
||||
@@ -256,6 +280,7 @@ func (c *Controller) UpdateDevice(ctx *gin.Context) {
|
||||
deviceID := ctx.Param("id")
|
||||
|
||||
// 1. 检查设备是否存在
|
||||
// 假设 FindByIDString 方法会预加载 DeviceTemplate 和 AreaController
|
||||
existingDevice, err := c.repo.FindByIDString(deviceID)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
@@ -290,16 +315,19 @@ func (c *Controller) UpdateDevice(ctx *gin.Context) {
|
||||
|
||||
// 3. 更新从数据库中查出的现有设备对象的字段
|
||||
existingDevice.Name = req.Name
|
||||
existingDevice.Type = req.Type
|
||||
existingDevice.SubType = req.SubType
|
||||
existingDevice.ParentID = req.ParentID
|
||||
existingDevice.DeviceTemplateID = req.DeviceTemplateID
|
||||
existingDevice.AreaControllerID = req.AreaControllerID
|
||||
existingDevice.Location = req.Location
|
||||
existingDevice.Properties = propertiesJSON
|
||||
|
||||
// 在更新设备前进行自检
|
||||
if !existingDevice.SelfCheck() {
|
||||
c.logger.Errorf("%s: 设备属性自检失败: %v", actionType, existingDevice)
|
||||
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "设备属性不符合要求", actionType, "设备属性自检失败", existingDevice)
|
||||
// 注意:这里的 SelfCheck 依赖于 DeviceTemplate 和 AreaController 字段,
|
||||
// 但在更新时这些关联对象可能尚未完全加载。如果 SelfCheck 内部需要这些关联对象,
|
||||
// 则需要在调用 SelfCheck 之前手动加载或调整 SelfCheck 逻辑。
|
||||
// 目前假设 SelfCheck 仅检查 ID 和 Properties。
|
||||
if err := existingDevice.SelfCheck(); err != nil {
|
||||
c.logger.Errorf("%s: 设备属性自检失败: %v", actionType, err)
|
||||
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "设备属性不符合要求: "+err.Error(), actionType, "设备属性自检失败", existingDevice)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -310,10 +338,18 @@ func (c *Controller) UpdateDevice(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := newDeviceResponse(existingDevice)
|
||||
// 为了在响应中包含 DeviceTemplateName 和 AreaControllerName,需要重新从数据库加载设备,并预加载关联。
|
||||
updatedDevice, err := c.repo.FindByID(existingDevice.ID)
|
||||
if err != nil {
|
||||
c.logger.Errorf("%s: 序列化响应失败: %v, Device: %+v", actionType, err, existingDevice)
|
||||
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "设备更新成功,但响应生成失败", actionType, "响应序列化失败", existingDevice)
|
||||
c.logger.Errorf("%s: 重新加载更新的设备失败: %v", actionType, err)
|
||||
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "设备更新成功,但重新加载设备失败", actionType, "重新加载设备失败", existingDevice)
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := newDeviceResponse(updatedDevice)
|
||||
if err != nil {
|
||||
c.logger.Errorf("%s: 序列化响应失败: %v, Device: %+v", actionType, err, updatedDevice)
|
||||
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "设备更新成功,但响应生成失败", actionType, "响应序列化失败", updatedDevice)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -346,7 +382,7 @@ func (c *Controller) DeleteDevice(ctx *gin.Context) {
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
c.logger.Warnf("%s: 设备不存在, ID: %s", actionType, deviceID)
|
||||
controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "设备不存在", actionType, "设备不存在", deviceID)
|
||||
controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "设备未找到", actionType, "设备不存在", deviceID)
|
||||
return
|
||||
}
|
||||
c.logger.Errorf("%s: 查找设备失败: %v, ID: %s", actionType, err, deviceID)
|
||||
|
||||
Reference in New Issue
Block a user