实现任务2.2
This commit is contained in:
373
internal/app/service/device_service.go
Normal file
373
internal/app/service/device_service.go
Normal file
@@ -0,0 +1,373 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/domain/device"
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
|
||||
)
|
||||
|
||||
// DeviceService 定义了应用层的设备服务接口,用于协调设备相关的业务逻辑。
|
||||
type DeviceService interface {
|
||||
CreateDevice(req *dto.CreateDeviceRequest) (*dto.DeviceResponse, error)
|
||||
GetDevice(id string) (*dto.DeviceResponse, error)
|
||||
ListDevices() ([]*dto.DeviceResponse, error)
|
||||
UpdateDevice(id string, req *dto.UpdateDeviceRequest) (*dto.DeviceResponse, error)
|
||||
DeleteDevice(id string) error
|
||||
ManualControl(id string, req *dto.ManualControlDeviceRequest) error
|
||||
|
||||
CreateAreaController(req *dto.CreateAreaControllerRequest) (*dto.AreaControllerResponse, error)
|
||||
GetAreaController(id string) (*dto.AreaControllerResponse, error)
|
||||
ListAreaControllers() ([]*dto.AreaControllerResponse, error)
|
||||
UpdateAreaController(id string, req *dto.UpdateAreaControllerRequest) (*dto.AreaControllerResponse, error)
|
||||
DeleteAreaController(id string) error
|
||||
|
||||
CreateDeviceTemplate(req *dto.CreateDeviceTemplateRequest) (*dto.DeviceTemplateResponse, error)
|
||||
GetDeviceTemplate(id string) (*dto.DeviceTemplateResponse, error)
|
||||
ListDeviceTemplates() ([]*dto.DeviceTemplateResponse, error)
|
||||
UpdateDeviceTemplate(id string, req *dto.UpdateDeviceTemplateRequest) (*dto.DeviceTemplateResponse, error)
|
||||
DeleteDeviceTemplate(id string) error
|
||||
}
|
||||
|
||||
// deviceService 是 DeviceService 接口的具体实现。
|
||||
type deviceService struct {
|
||||
deviceRepo repository.DeviceRepository
|
||||
areaControllerRepo repository.AreaControllerRepository
|
||||
deviceTemplateRepo repository.DeviceTemplateRepository
|
||||
deviceDomainSvc device.Service // 依赖领域服务
|
||||
}
|
||||
|
||||
// NewDeviceService 创建一个新的 DeviceService 实例。
|
||||
func NewDeviceService(
|
||||
deviceRepo repository.DeviceRepository,
|
||||
areaControllerRepo repository.AreaControllerRepository,
|
||||
deviceTemplateRepo repository.DeviceTemplateRepository,
|
||||
deviceDomainSvc device.Service,
|
||||
) DeviceService {
|
||||
return &deviceService{
|
||||
deviceRepo: deviceRepo,
|
||||
areaControllerRepo: areaControllerRepo,
|
||||
deviceTemplateRepo: deviceTemplateRepo,
|
||||
deviceDomainSvc: deviceDomainSvc,
|
||||
}
|
||||
}
|
||||
|
||||
// --- Devices ---
|
||||
|
||||
func (s *deviceService) CreateDevice(req *dto.CreateDeviceRequest) (*dto.DeviceResponse, error) {
|
||||
propertiesJSON, err := json.Marshal(req.Properties)
|
||||
if err != nil {
|
||||
return nil, err // Consider wrapping this error for better context
|
||||
}
|
||||
|
||||
device := &models.Device{
|
||||
Name: req.Name,
|
||||
DeviceTemplateID: req.DeviceTemplateID,
|
||||
AreaControllerID: req.AreaControllerID,
|
||||
Location: req.Location,
|
||||
Properties: propertiesJSON,
|
||||
}
|
||||
|
||||
if err := device.SelfCheck(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.deviceRepo.Create(device); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
createdDevice, err := s.deviceRepo.FindByID(device.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dto.NewDeviceResponse(createdDevice)
|
||||
}
|
||||
|
||||
func (s *deviceService) GetDevice(id string) (*dto.DeviceResponse, error) {
|
||||
device, err := s.deviceRepo.FindByIDString(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dto.NewDeviceResponse(device)
|
||||
}
|
||||
|
||||
func (s *deviceService) ListDevices() ([]*dto.DeviceResponse, error) {
|
||||
devices, err := s.deviceRepo.ListAll()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dto.NewListDeviceResponse(devices)
|
||||
}
|
||||
|
||||
func (s *deviceService) UpdateDevice(id string, req *dto.UpdateDeviceRequest) (*dto.DeviceResponse, error) {
|
||||
existingDevice, err := s.deviceRepo.FindByIDString(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
propertiesJSON, err := json.Marshal(req.Properties)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
existingDevice.Name = req.Name
|
||||
existingDevice.DeviceTemplateID = req.DeviceTemplateID
|
||||
existingDevice.AreaControllerID = req.AreaControllerID
|
||||
existingDevice.Location = req.Location
|
||||
existingDevice.Properties = propertiesJSON
|
||||
|
||||
if err := existingDevice.SelfCheck(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.deviceRepo.Update(existingDevice); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
updatedDevice, err := s.deviceRepo.FindByID(existingDevice.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dto.NewDeviceResponse(updatedDevice)
|
||||
}
|
||||
|
||||
func (s *deviceService) DeleteDevice(id string) error {
|
||||
idUint, err := strconv.ParseUint(id, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Check if device exists before deleting
|
||||
_, err = s.deviceRepo.FindByID(uint(idUint))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.deviceRepo.Delete(uint(idUint))
|
||||
}
|
||||
|
||||
func (s *deviceService) ManualControl(id string, req *dto.ManualControlDeviceRequest) error {
|
||||
dev, err := s.deviceRepo.FindByIDString(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if req.Action == nil {
|
||||
return s.deviceDomainSvc.Collect(dev.AreaControllerID, []*models.Device{dev})
|
||||
} else {
|
||||
action := device.DeviceActionStart
|
||||
switch *req.Action {
|
||||
case "off":
|
||||
action = device.DeviceActionStop
|
||||
case "on":
|
||||
action = device.DeviceActionStart
|
||||
default:
|
||||
return errors.New("invalid action")
|
||||
}
|
||||
return s.deviceDomainSvc.Switch(dev, action)
|
||||
}
|
||||
}
|
||||
|
||||
// --- Area Controllers ---
|
||||
|
||||
func (s *deviceService) CreateAreaController(req *dto.CreateAreaControllerRequest) (*dto.AreaControllerResponse, error) {
|
||||
propertiesJSON, err := json.Marshal(req.Properties)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ac := &models.AreaController{
|
||||
Name: req.Name,
|
||||
NetworkID: req.NetworkID,
|
||||
Location: req.Location,
|
||||
Properties: propertiesJSON,
|
||||
}
|
||||
|
||||
if err := ac.SelfCheck(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.areaControllerRepo.Create(ac); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dto.NewAreaControllerResponse(ac)
|
||||
}
|
||||
|
||||
func (s *deviceService) GetAreaController(id string) (*dto.AreaControllerResponse, error) {
|
||||
idUint, err := strconv.ParseUint(id, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ac, err := s.areaControllerRepo.FindByID(uint(idUint))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dto.NewAreaControllerResponse(ac)
|
||||
}
|
||||
|
||||
func (s *deviceService) ListAreaControllers() ([]*dto.AreaControllerResponse, error) {
|
||||
acs, err := s.areaControllerRepo.ListAll()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dto.NewListAreaControllerResponse(acs)
|
||||
}
|
||||
|
||||
func (s *deviceService) UpdateAreaController(id string, req *dto.UpdateAreaControllerRequest) (*dto.AreaControllerResponse, error) {
|
||||
idUint, err := strconv.ParseUint(id, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
existingAC, err := s.areaControllerRepo.FindByID(uint(idUint))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
propertiesJSON, err := json.Marshal(req.Properties)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
existingAC.Name = req.Name
|
||||
existingAC.NetworkID = req.NetworkID
|
||||
existingAC.Location = req.Location
|
||||
existingAC.Properties = propertiesJSON
|
||||
|
||||
if err := existingAC.SelfCheck(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.areaControllerRepo.Update(existingAC); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dto.NewAreaControllerResponse(existingAC)
|
||||
}
|
||||
|
||||
func (s *deviceService) DeleteAreaController(id string) error {
|
||||
idUint, err := strconv.ParseUint(id, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = s.areaControllerRepo.FindByID(uint(idUint))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.areaControllerRepo.Delete(uint(idUint))
|
||||
}
|
||||
|
||||
// --- Device Templates ---
|
||||
|
||||
func (s *deviceService) CreateDeviceTemplate(req *dto.CreateDeviceTemplateRequest) (*dto.DeviceTemplateResponse, error) {
|
||||
commandsJSON, err := json.Marshal(req.Commands)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
valuesJSON, err := json.Marshal(req.Values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
deviceTemplate := &models.DeviceTemplate{
|
||||
Name: req.Name,
|
||||
Manufacturer: req.Manufacturer,
|
||||
Description: req.Description,
|
||||
Category: req.Category,
|
||||
Commands: commandsJSON,
|
||||
Values: valuesJSON,
|
||||
}
|
||||
|
||||
if err := deviceTemplate.SelfCheck(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.deviceTemplateRepo.Create(deviceTemplate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dto.NewDeviceTemplateResponse(deviceTemplate)
|
||||
}
|
||||
|
||||
func (s *deviceService) GetDeviceTemplate(id string) (*dto.DeviceTemplateResponse, error) {
|
||||
idUint, err := strconv.ParseUint(id, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
deviceTemplate, err := s.deviceTemplateRepo.FindByID(uint(idUint))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dto.NewDeviceTemplateResponse(deviceTemplate)
|
||||
}
|
||||
|
||||
func (s *deviceService) ListDeviceTemplates() ([]*dto.DeviceTemplateResponse, error) {
|
||||
deviceTemplates, err := s.deviceTemplateRepo.ListAll()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dto.NewListDeviceTemplateResponse(deviceTemplates)
|
||||
}
|
||||
|
||||
func (s *deviceService) UpdateDeviceTemplate(id string, req *dto.UpdateDeviceTemplateRequest) (*dto.DeviceTemplateResponse, error) {
|
||||
idUint, err := strconv.ParseUint(id, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
existingDeviceTemplate, err := s.deviceTemplateRepo.FindByID(uint(idUint))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
commandsJSON, err := json.Marshal(req.Commands)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
valuesJSON, err := json.Marshal(req.Values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
existingDeviceTemplate.Name = req.Name
|
||||
existingDeviceTemplate.Manufacturer = req.Manufacturer
|
||||
existingDeviceTemplate.Description = req.Description
|
||||
existingDeviceTemplate.Category = req.Category
|
||||
existingDeviceTemplate.Commands = commandsJSON
|
||||
existingDeviceTemplate.Values = valuesJSON
|
||||
|
||||
if err := existingDeviceTemplate.SelfCheck(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.deviceTemplateRepo.Update(existingDeviceTemplate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dto.NewDeviceTemplateResponse(existingDeviceTemplate)
|
||||
}
|
||||
|
||||
func (s *deviceService) DeleteDeviceTemplate(id string) error {
|
||||
idUint, err := strconv.ParseUint(id, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = s.deviceTemplateRepo.FindByID(uint(idUint))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.deviceTemplateRepo.Delete(uint(idUint))
|
||||
}
|
||||
Reference in New Issue
Block a user