调整 Controller

This commit is contained in:
2025-09-30 00:18:21 +08:00
parent 56dbb680a7
commit ab9842dc10

View File

@@ -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)