diff --git a/internal/api/api.go b/internal/api/api.go index 4d1355d..a8022f8 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -11,6 +11,7 @@ import ( "git.huangwc.com/pig/pig-farm-controller/internal/api/middleware" "git.huangwc.com/pig/pig-farm-controller/internal/config" + "git.huangwc.com/pig/pig-farm-controller/internal/controller/device" "git.huangwc.com/pig/pig-farm-controller/internal/controller/operation" "git.huangwc.com/pig/pig-farm-controller/internal/controller/user" "git.huangwc.com/pig/pig-farm-controller/internal/logs" @@ -36,6 +37,9 @@ type API struct { // operationController 操作历史控制器 operationController *operation.Controller + // deviceController 设备控制控制器 + deviceController *device.Controller + // authMiddleware 鉴权中间件 authMiddleware *middleware.AuthMiddleware @@ -45,7 +49,7 @@ type API struct { // NewAPI 创建并返回一个新的API实例 // 初始化Gin引擎和相关配置 -func NewAPI(cfg *config.Config, userRepo repository.UserRepo, operationHistoryRepo repository.OperationHistoryRepo) *API { +func NewAPI(cfg *config.Config, userRepo repository.UserRepo, operationHistoryRepo repository.OperationHistoryRepo, deviceControlRepo repository.DeviceControlRepo) *API { // 设置Gin为发布模式 gin.SetMode(gin.ReleaseMode) @@ -75,6 +79,9 @@ func NewAPI(cfg *config.Config, userRepo repository.UserRepo, operationHistoryRe // 创建操作历史控制器 operationController := operation.NewController(operationHistoryRepo) + // 创建设备控制控制器 + deviceController := device.NewController(deviceControlRepo) + // 创建鉴权中间件 authMiddleware := middleware.NewAuthMiddleware(userRepo) @@ -83,6 +90,7 @@ func NewAPI(cfg *config.Config, userRepo repository.UserRepo, operationHistoryRe config: cfg, userController: userController, operationController: operationController, + deviceController: deviceController, authMiddleware: authMiddleware, logger: logs.NewLogger(), } @@ -157,29 +165,12 @@ func (a *API) setupRoutes() { operationGroup.GET("/:id", a.operationController.Get) } - // 示例受保护路由 - protectedGroup.GET("/profile", func(c *gin.Context) { - // 从上下文中获取用户信息 - userValue, exists := c.Get("user") - if !exists { - c.JSON(http.StatusUnauthorized, gin.H{"error": "无法获取用户信息"}) - return - } + // 设备控制相关路由 + deviceGroup := protectedGroup.Group("/device") + { + deviceGroup.POST("/switch", a.deviceController.Switch) + } - user, ok := userValue.(*middleware.AuthUser) - if !ok { - c.JSON(http.StatusInternalServerError, gin.H{"error": "用户信息格式错误"}) - return - } - - c.JSON(http.StatusOK, gin.H{ - "message": "获取用户信息成功", - "user": map[string]interface{}{ - "id": user.ID, - "username": user.Username, - }, - }) - }) } // TODO: 添加更多路由 diff --git a/internal/controller/device/device.go b/internal/controller/device/device.go new file mode 100644 index 0000000..117c534 --- /dev/null +++ b/internal/controller/device/device.go @@ -0,0 +1,91 @@ +// Package device 提供设备控制相关功能的控制器 +// 实现设备控制、查询等操作 +package device + +import ( + "net/http" + + "git.huangwc.com/pig/pig-farm-controller/internal/api/middleware" + "git.huangwc.com/pig/pig-farm-controller/internal/logs" + "git.huangwc.com/pig/pig-farm-controller/internal/model" + "git.huangwc.com/pig/pig-farm-controller/internal/storage/repository" + "github.com/gin-gonic/gin" +) + +// Controller 设备控制控制器 +type Controller struct { + deviceControlRepo repository.DeviceControlRepo + logger *logs.Logger +} + +// NewController 创建设备控制控制器实例 +func NewController(deviceControlRepo repository.DeviceControlRepo) *Controller { + return &Controller{ + deviceControlRepo: deviceControlRepo, + logger: logs.NewLogger(), + } +} + +// ControlRequest 设备控制请求结构体 +type ControlRequest struct { + PigPenID string `json:"pig_pen_id" binding:"required"` + DeviceType string `json:"device_type" binding:"required,oneof=fan water_curtain"` + DeviceID string `json:"device_id" binding:"required"` + Action string `json:"action" binding:"required,oneof=on off"` +} + +// Switch 设备控制接口 +func (c *Controller) Switch(ctx *gin.Context) { + // 从上下文中获取用户信息 + userValue, exists := ctx.Get("user") + if !exists { + ctx.JSON(http.StatusUnauthorized, gin.H{"error": "无法获取用户信息"}) + return + } + + user, ok := userValue.(*middleware.AuthUser) + if !ok { + ctx.JSON(http.StatusInternalServerError, gin.H{"error": "用户信息格式错误"}) + return + } + + var req ControlRequest + if err := ctx.ShouldBindJSON(&req); err != nil { + ctx.JSON(http.StatusBadRequest, gin.H{"error": "请求参数错误"}) + return + } + + // TODO: 实际的设备控制逻辑 + // 这里暂时用TODO代替具体逻辑 + + // 创建设备控制记录 + control := &model.DeviceControl{ + UserID: user.ID, + PigPenID: req.PigPenID, + DeviceType: model.DeviceType(req.DeviceType), + DeviceID: req.DeviceID, + Action: req.Action, + Status: "success", // 假设控制成功 + Result: "设备控制成功", + } + + if err := c.deviceControlRepo.Create(control); err != nil { + c.logger.Error("创建设备控制记录失败: " + err.Error()) + ctx.JSON(http.StatusInternalServerError, gin.H{"error": "设备控制失败"}) + return + } + + ctx.JSON(http.StatusOK, gin.H{ + "message": "设备控制成功", + "data": map[string]interface{}{ + "id": control.ID, + "pig_pen_id": control.PigPenID, + "device_type": control.DeviceType, + "device_id": control.DeviceID, + "action": control.Action, + "status": control.Status, + "result": control.Result, + "created_at": control.CreatedAt, + }, + }) +} diff --git a/internal/core/application.go b/internal/core/application.go index 7d3d012..1eeaf69 100644 --- a/internal/core/application.go +++ b/internal/core/application.go @@ -32,6 +32,9 @@ type Application struct { // OperationHistoryRepo 操作历史仓库实例 OperationHistoryRepo repository.OperationHistoryRepo + // DeviceControlRepo 设备控制仓库实例 + DeviceControlRepo repository.DeviceControlRepo + // Config 应用配置 Config *config.Config @@ -59,8 +62,11 @@ func NewApplication(cfg *config.Config) *Application { // 初始化操作历史仓库 operationHistoryRepo := repository.NewOperationHistoryRepo(store.GetDB()) + // 初始化设备控制仓库 + deviceControlRepo := repository.NewDeviceControlRepo(store.GetDB()) + // 初始化API组件 - apiInstance := api.NewAPI(cfg, userRepo, operationHistoryRepo) + apiInstance := api.NewAPI(cfg, userRepo, operationHistoryRepo, deviceControlRepo) // 初始化任务执行器组件(使用5个工作协程) taskExecutor := task.NewExecutor(5) @@ -71,6 +77,7 @@ func NewApplication(cfg *config.Config) *Application { TaskExecutor: taskExecutor, UserRepo: userRepo, OperationHistoryRepo: operationHistoryRepo, + DeviceControlRepo: deviceControlRepo, Config: cfg, logger: logs.NewLogger(), } diff --git a/internal/model/device.go b/internal/model/device.go new file mode 100644 index 0000000..8bbbc3a --- /dev/null +++ b/internal/model/device.go @@ -0,0 +1,61 @@ +// Package model 提供数据模型定义 +// 包含设备控制等相关数据结构 +package model + +import ( + "time" + + "gorm.io/gorm" +) + +// DeviceType 设备类型枚举 +type DeviceType string + +const ( + // DeviceTypeFan 风机 + DeviceTypeFan DeviceType = "fan" + + // DeviceTypeWaterCurtain 水帘 + DeviceTypeWaterCurtain DeviceType = "water_curtain" +) + +// DeviceControl 代表设备控制记录 +type DeviceControl struct { + // ID 记录ID + ID uint `gorm:"primaryKey;column:id" json:"id"` + + // UserID 用户ID + UserID uint `gorm:"not null;column:user_id;index" json:"user_id"` + + // PigPenID 猪舍编号 + PigPenID string `gorm:"not null;column:pig_pen_id" json:"pig_pen_id"` + + // DeviceType 设备类型 + DeviceType DeviceType `gorm:"not null;column:device_type" json:"device_type"` + + // DeviceID 设备编号 + DeviceID string `gorm:"not null;column:device_id" json:"device_id"` + + // Action 控制动作(开/关) + Action string `gorm:"not null;column:action" json:"action"` + + // Status 控制状态(成功/失败) + Status string `gorm:"not null;column:status" json:"status"` + + // Result 控制结果详情(可选) + Result string `gorm:"column:result" json:"result"` + + // CreatedAt 创建时间 + CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` + + // UpdatedAt 更新时间 + UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` + + // DeletedAt 删除时间(用于软删除) + DeletedAt gorm.DeletedAt `gorm:"index;column:deleted_at" json:"-"` +} + +// TableName 指定DeviceControl模型对应的数据库表名 +func (DeviceControl) TableName() string { + return "device_controls" +} diff --git a/internal/storage/repository/device.go b/internal/storage/repository/device.go new file mode 100644 index 0000000..516a375 --- /dev/null +++ b/internal/storage/repository/device.go @@ -0,0 +1,71 @@ +// Package repository 提供数据访问层实现 +// 包含设备控制等数据实体的仓库接口和实现 +package repository + +import ( + "git.huangwc.com/pig/pig-farm-controller/internal/model" + "gorm.io/gorm" +) + +// DeviceControlRepo 设备控制仓库接口 +type DeviceControlRepo interface { + // Create 创建设备控制记录 + Create(control *model.DeviceControl) error + + // FindByUserID 根据用户ID查找设备控制记录 + FindByUserID(userID uint) ([]*model.DeviceControl, error) + + // FindByID 根据ID查找设备控制记录 + FindByID(id uint) (*model.DeviceControl, error) + + // List 获取设备控制记录列表(分页) + List(offset, limit int) ([]*model.DeviceControl, error) +} + +// deviceControlRepo 设备控制仓库实现 +type deviceControlRepo struct { + db *gorm.DB +} + +// NewDeviceControlRepo 创建设备控制仓库实例 +func NewDeviceControlRepo(db *gorm.DB) DeviceControlRepo { + return &deviceControlRepo{ + db: db, + } +} + +// Create 创建设备控制记录 +func (r *deviceControlRepo) Create(control *model.DeviceControl) error { + result := r.db.Create(control) + return result.Error +} + +// FindByUserID 根据用户ID查找设备控制记录 +func (r *deviceControlRepo) FindByUserID(userID uint) ([]*model.DeviceControl, error) { + var controls []*model.DeviceControl + result := r.db.Where("user_id = ?", userID).Order("created_at DESC").Find(&controls) + if result.Error != nil { + return nil, result.Error + } + return controls, nil +} + +// FindByID 根据ID查找设备控制记录 +func (r *deviceControlRepo) FindByID(id uint) (*model.DeviceControl, error) { + var control model.DeviceControl + result := r.db.First(&control, id) + if result.Error != nil { + return nil, result.Error + } + return &control, nil +} + +// List 获取设备控制记录列表(分页) +func (r *deviceControlRepo) List(offset, limit int) ([]*model.DeviceControl, error) { + var controls []*model.DeviceControl + result := r.db.Offset(offset).Limit(limit).Order("created_at DESC").Find(&controls) + if result.Error != nil { + return nil, result.Error + } + return controls, nil +}