Files
pig-farm-controller/internal/infra/repository/device_repository.go
2025-09-29 17:27:42 +08:00

120 lines
4.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package repository
import (
"fmt"
"strconv"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
"gorm.io/gorm"
)
// DeviceRepository 定义了与设备模型相关的数据库操作接口
// 这一层抽象使得上层业务逻辑无需关心底层数据库的具体实现。
type DeviceRepository interface {
// Create 创建一个新设备记录
Create(device *models.Device) error
// FindByID 根据主键 ID 查找设备
FindByID(id uint) (*models.Device, error)
// FindByIDString 根据字符串形式的主键 ID 查找设备,方便控制器调用
FindByIDString(id string) (*models.Device, error)
// ListAll 获取所有设备的列表
ListAll() ([]*models.Device, error)
// ListByAreaControllerID 根据区域主控 ID 列出所有子设备。
ListByAreaControllerID(areaControllerID uint) ([]*models.Device, error)
// Update 更新一个已有的设备信息
Update(device *models.Device) error
// Delete 根据主键 ID 删除一个设备
Delete(id uint) error
// FindByAreaControllerAndPhysicalAddress 根据区域主控ID和物理地址(总线号、总线地址)查找设备
FindByAreaControllerAndPhysicalAddress(areaControllerID uint, busNumber int, busAddress int) (*models.Device, error)
}
// gormDeviceRepository 是 DeviceRepository 的 GORM 实现
type gormDeviceRepository struct {
db *gorm.DB
}
// NewGormDeviceRepository 创建一个新的 DeviceRepository GORM 实现实例
func NewGormDeviceRepository(db *gorm.DB) DeviceRepository {
return &gormDeviceRepository{db: db}
}
// Create 创建一个新的设备记录
func (r *gormDeviceRepository) Create(device *models.Device) error {
return r.db.Create(device).Error
}
// FindByID 根据 ID 查找设备
func (r *gormDeviceRepository) FindByID(id uint) (*models.Device, error) {
var device models.Device
if err := r.db.Preload("AreaController").Preload("DeviceTemplate").First(&device, id).Error; err != nil {
return nil, err
}
return &device, nil
}
// FindByIDString 根据字符串形式的主键 ID 查找设备
func (r *gormDeviceRepository) FindByIDString(id string) (*models.Device, error) {
// 将字符串ID转换为uint64
idInt, err := strconv.ParseUint(id, 10, 64)
if err != nil {
// 如果转换失败说明ID格式不正确返回一个明确的错误
return nil, fmt.Errorf("无效的设备ID格式: %w", err)
}
// 调用已有的 FindByID 方法
return r.FindByID(uint(idInt))
}
// ListAll 获取所有设备的列表
func (r *gormDeviceRepository) ListAll() ([]*models.Device, error) {
var devices []*models.Device
if err := r.db.Preload("AreaController").Preload("DeviceTemplate").Find(&devices).Error; err != nil {
return nil, err
}
return devices, nil
}
// ListByAreaControllerID 根据区域主控 ID 列出所有子设备
func (r *gormDeviceRepository) ListByAreaControllerID(areaControllerID uint) ([]*models.Device, error) {
var devices []*models.Device
err := r.db.Preload("AreaController").Preload("DeviceTemplate").Where("area_controller_id = ?", areaControllerID).Find(&devices).Error
if err != nil {
return nil, err
}
return devices, nil
}
// Update 更新一个已有的设备信息
// GORM 的 Save 方法会自动处理主键存在时更新,不存在时创建的逻辑,但这里我们明确用于更新。
func (r *gormDeviceRepository) Update(device *models.Device) error {
return r.db.Save(device).Error
}
// Delete 根据 ID 删除一个设备
// GORM 使用软删除,记录不会从数据库中物理移除,而是设置 DeletedAt 字段。
func (r *gormDeviceRepository) Delete(id uint) error {
return r.db.Delete(&models.Device{}, id).Error
}
// FindByAreaControllerAndPhysicalAddress 根据区域主控ID和物理地址(总线号、总线地址)查找设备
func (r *gormDeviceRepository) FindByAreaControllerAndPhysicalAddress(areaControllerID uint, busNumber int, busAddress int) (*models.Device, error) {
var device models.Device
err := r.db.Preload("AreaController").Preload("DeviceTemplate").
Where("area_controller_id = ?", areaControllerID).
Where("properties->>'bus_number' = ?", strconv.Itoa(busNumber)).
Where("properties->>'bus_address' = ?", strconv.Itoa(busAddress)).
First(&device).Error
if err != nil {
return nil, fmt.Errorf("根据区域主控ID %d 和物理地址 (总线号: %d, 总线地址: %d) 查找设备失败: %w", areaControllerID, busNumber, busAddress, err)
}
return &device, nil
}