1.注册饲喂计划相关路由
2. 实现create接口
This commit is contained in:
@@ -69,7 +69,16 @@ type API struct {
|
|||||||
|
|
||||||
// NewAPI 创建并返回一个新的API实例
|
// NewAPI 创建并返回一个新的API实例
|
||||||
// 初始化Gin引擎和相关配置
|
// 初始化Gin引擎和相关配置
|
||||||
func NewAPI(cfg *config.Config, userRepo repository.UserRepo, operationHistoryRepo repository.OperationHistoryRepo, deviceControlRepo repository.DeviceControlRepo, deviceRepo repository.DeviceRepo, websocketManager *websocket.Manager, heartbeatService *service.HeartbeatService, deviceStatusPool *service.DeviceStatusPool) *API {
|
func NewAPI(cfg *config.Config,
|
||||||
|
userRepo repository.UserRepo,
|
||||||
|
operationHistoryRepo repository.OperationHistoryRepo,
|
||||||
|
deviceControlRepo repository.DeviceControlRepo,
|
||||||
|
deviceRepo repository.DeviceRepo,
|
||||||
|
feedRepo repository.FeedPlanRepo,
|
||||||
|
websocketManager *websocket.Manager,
|
||||||
|
heartbeatService *service.HeartbeatService,
|
||||||
|
deviceStatusPool *service.DeviceStatusPool,
|
||||||
|
) *API {
|
||||||
// 设置Gin为发布模式
|
// 设置Gin为发布模式
|
||||||
gin.SetMode(gin.DebugMode)
|
gin.SetMode(gin.DebugMode)
|
||||||
|
|
||||||
@@ -103,7 +112,7 @@ func NewAPI(cfg *config.Config, userRepo repository.UserRepo, operationHistoryRe
|
|||||||
deviceController := device.NewController(deviceControlRepo, deviceRepo, websocketManager, heartbeatService, deviceStatusPool)
|
deviceController := device.NewController(deviceControlRepo, deviceRepo, websocketManager, heartbeatService, deviceStatusPool)
|
||||||
|
|
||||||
// 创建饲喂管理控制器
|
// 创建饲喂管理控制器
|
||||||
feedController := feed.NewController()
|
feedController := feed.NewController(feedRepo)
|
||||||
|
|
||||||
// 创建远程控制控制器
|
// 创建远程控制控制器
|
||||||
remoteController := remote.NewController(websocketManager)
|
remoteController := remote.NewController(websocketManager)
|
||||||
@@ -235,6 +244,9 @@ func (a *API) setupRoutes() {
|
|||||||
{
|
{
|
||||||
feedGroup.GET("/plan/list", a.feedController.ListPlans)
|
feedGroup.GET("/plan/list", a.feedController.ListPlans)
|
||||||
feedGroup.GET("/plan/detail", a.feedController.Detail)
|
feedGroup.GET("/plan/detail", a.feedController.Detail)
|
||||||
|
feedGroup.POST("/plan/create", a.feedController.Create)
|
||||||
|
feedGroup.POST("/plan/update", a.feedController.Update)
|
||||||
|
feedGroup.POST("/plan/delete", a.feedController.Delete)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 远程控制相关路由
|
// 远程控制相关路由
|
||||||
|
|||||||
@@ -29,6 +29,100 @@ func NewController(feedPlanRepo repository.FeedPlanRepo) *Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateRequest 创建计划请求结构体
|
||||||
|
type CreateRequest struct {
|
||||||
|
// Name 计划名称
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// Description 计划描述
|
||||||
|
Description string `json:"description"`
|
||||||
|
|
||||||
|
// Type 计划类型(手动触发/自动触发)
|
||||||
|
Type model.FeedingPlanType `json:"type"`
|
||||||
|
|
||||||
|
// Enabled 是否启用
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
|
||||||
|
// ScheduleCron 定时任务表达式(仅当Type为auto时有效)
|
||||||
|
ScheduleCron *string `json:"scheduleCron"`
|
||||||
|
|
||||||
|
// ExecutionLimit 执行次数限制(0表示无限制,仅当Type为auto时有效)
|
||||||
|
ExecutionLimit int `json:"executionLimit"`
|
||||||
|
|
||||||
|
// ParentID 父计划ID(用于支持子计划结构)
|
||||||
|
ParentID *uint `json:"parentID"`
|
||||||
|
|
||||||
|
// OrderInParent 在父计划中的执行顺序
|
||||||
|
OrderInParent *int `json:"orderInParent"`
|
||||||
|
|
||||||
|
// IsMaster 是否为主计划(主计划可以包含子计划)
|
||||||
|
IsMaster bool `json:"isMaster"`
|
||||||
|
|
||||||
|
// Steps 计划步骤列表
|
||||||
|
Steps []FeedingPlanStep `json:"steps"`
|
||||||
|
|
||||||
|
// SubPlans 子计划列表
|
||||||
|
SubPlans []CreateRequest `json:"subPlans"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create 创建饲料计划
|
||||||
|
func (c *Controller) Create(ctx *gin.Context) {
|
||||||
|
var req CreateRequest
|
||||||
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||||
|
controller.SendErrorResponse(ctx, controller.InvalidParameterCode, "请求参数错误: "+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换请求结构体为模型
|
||||||
|
plan := c.convertToCreateModel(&req)
|
||||||
|
|
||||||
|
// 调用仓库创建计划
|
||||||
|
if err := c.feedPlanRepo.CreateFeedingPlan(plan); err != nil {
|
||||||
|
c.logger.Error("创建计划失败: " + err.Error())
|
||||||
|
controller.SendErrorResponse(ctx, controller.InternalServerErrorCode, "创建计划失败")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.SendSuccessResponse(ctx, "创建计划成功", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// convertToCreateModel 将创建请求结构体转换为数据库模型
|
||||||
|
func (c *Controller) convertToCreateModel(req *CreateRequest) *model.FeedingPlan {
|
||||||
|
plan := &model.FeedingPlan{
|
||||||
|
Name: req.Name,
|
||||||
|
Description: req.Description,
|
||||||
|
Type: req.Type,
|
||||||
|
Enabled: req.Enabled,
|
||||||
|
ScheduleCron: req.ScheduleCron,
|
||||||
|
ExecutionLimit: req.ExecutionLimit,
|
||||||
|
ParentID: req.ParentID,
|
||||||
|
OrderInParent: req.OrderInParent,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换步骤
|
||||||
|
plan.Steps = make([]model.FeedingPlanStep, len(req.Steps))
|
||||||
|
for i, step := range req.Steps {
|
||||||
|
plan.Steps[i] = model.FeedingPlanStep{
|
||||||
|
// ID在创建时不需要设置
|
||||||
|
// PlanID会在创建过程中自动设置
|
||||||
|
StepOrder: step.StepOrder,
|
||||||
|
DeviceID: step.DeviceID,
|
||||||
|
TargetValue: step.TargetValue,
|
||||||
|
Action: step.Action,
|
||||||
|
ScheduleCron: step.ScheduleCron,
|
||||||
|
ExecutionLimit: step.ExecutionLimit,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换子计划
|
||||||
|
plan.SubPlans = make([]model.FeedingPlan, len(req.SubPlans))
|
||||||
|
for i, subReq := range req.SubPlans {
|
||||||
|
plan.SubPlans[i] = *c.convertToCreateModel(&subReq)
|
||||||
|
}
|
||||||
|
|
||||||
|
return plan
|
||||||
|
}
|
||||||
|
|
||||||
// Delete 删除饲料计划
|
// Delete 删除饲料计划
|
||||||
func (c *Controller) Delete(ctx *gin.Context) {
|
func (c *Controller) Delete(ctx *gin.Context) {
|
||||||
// 获取路径参数中的计划ID
|
// 获取路径参数中的计划ID
|
||||||
@@ -100,17 +194,40 @@ func (c *Controller) ListPlans(ctx *gin.Context) {
|
|||||||
|
|
||||||
// UpdateRequest 更新计划请求结构体
|
// UpdateRequest 更新计划请求结构体
|
||||||
type UpdateRequest struct {
|
type UpdateRequest struct {
|
||||||
|
// ID 计划ID
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
|
|
||||||
|
// Name 计划名称
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// Description 计划描述
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
|
|
||||||
|
// Type 计划类型(手动触发/自动触发)
|
||||||
Type model.FeedingPlanType `json:"type"`
|
Type model.FeedingPlanType `json:"type"`
|
||||||
|
|
||||||
|
// Enabled 是否启用
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
|
|
||||||
|
// ScheduleCron 定时任务表达式(仅当Type为auto时有效)
|
||||||
ScheduleCron *string `json:"scheduleCron"`
|
ScheduleCron *string `json:"scheduleCron"`
|
||||||
|
|
||||||
|
// ExecutionLimit 执行次数限制(0表示无限制,仅当Type为auto时有效)
|
||||||
ExecutionLimit int `json:"executionLimit"`
|
ExecutionLimit int `json:"executionLimit"`
|
||||||
|
|
||||||
|
// ParentID 父计划ID(用于支持子计划结构)
|
||||||
ParentID *uint `json:"parentID"`
|
ParentID *uint `json:"parentID"`
|
||||||
|
|
||||||
|
// OrderInParent 在父计划中的执行顺序
|
||||||
OrderInParent *int `json:"orderInParent"`
|
OrderInParent *int `json:"orderInParent"`
|
||||||
|
|
||||||
|
// IsMaster 是否为主计划(主计划可以包含子计划)
|
||||||
IsMaster bool `json:"isMaster"`
|
IsMaster bool `json:"isMaster"`
|
||||||
|
|
||||||
|
// Steps 计划步骤列表
|
||||||
Steps []FeedingPlanStep `json:"steps"`
|
Steps []FeedingPlanStep `json:"steps"`
|
||||||
|
|
||||||
|
// SubPlans 子计划列表
|
||||||
SubPlans []UpdateRequest `json:"subPlans"`
|
SubPlans []UpdateRequest `json:"subPlans"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,20 +410,7 @@ func (c *Controller) convertToDetailResponse(plan *model.FeedingPlan) *DetailRes
|
|||||||
// 转换子计划
|
// 转换子计划
|
||||||
for i, subPlan := range plan.SubPlans {
|
for i, subPlan := range plan.SubPlans {
|
||||||
// 递归转换子计划
|
// 递归转换子计划
|
||||||
subPlanModel := &model.FeedingPlan{
|
resp.SubPlans[i] = *c.convertToDetailResponse(&subPlan)
|
||||||
ID: subPlan.ID,
|
|
||||||
Name: subPlan.Name,
|
|
||||||
Description: subPlan.Description,
|
|
||||||
Type: subPlan.Type,
|
|
||||||
Enabled: subPlan.Enabled,
|
|
||||||
ScheduleCron: subPlan.ScheduleCron,
|
|
||||||
ExecutionLimit: subPlan.ExecutionLimit,
|
|
||||||
ParentID: subPlan.ParentID,
|
|
||||||
OrderInParent: subPlan.OrderInParent,
|
|
||||||
Steps: subPlan.Steps,
|
|
||||||
SubPlans: subPlan.SubPlans,
|
|
||||||
}
|
|
||||||
resp.SubPlans[i] = *c.convertToDetailResponse(subPlanModel)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp
|
return resp
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ type Application struct {
|
|||||||
// DeviceRepo 设备仓库实例
|
// DeviceRepo 设备仓库实例
|
||||||
DeviceRepo repository.DeviceRepo
|
DeviceRepo repository.DeviceRepo
|
||||||
|
|
||||||
|
// FeedPlanRepo 投喂计划仓库实例
|
||||||
|
FeedPlanRepo repository.FeedPlanRepo
|
||||||
|
|
||||||
// WebsocketManager WebSocket管理器
|
// WebsocketManager WebSocket管理器
|
||||||
WebsocketManager *websocket.Manager
|
WebsocketManager *websocket.Manager
|
||||||
|
|
||||||
@@ -97,6 +100,8 @@ func (app *Application) Start() error {
|
|||||||
// 初始化设备仓库
|
// 初始化设备仓库
|
||||||
app.DeviceRepo = repository.NewDeviceRepo(app.Storage.GetDB())
|
app.DeviceRepo = repository.NewDeviceRepo(app.Storage.GetDB())
|
||||||
|
|
||||||
|
app.FeedPlanRepo = repository.NewFeedPlanRepo(app.Storage.GetDB())
|
||||||
|
|
||||||
// 初始化设备状态池
|
// 初始化设备状态池
|
||||||
app.DeviceStatusPool = service.NewDeviceStatusPool()
|
app.DeviceStatusPool = service.NewDeviceStatusPool()
|
||||||
|
|
||||||
@@ -109,7 +114,16 @@ func (app *Application) Start() error {
|
|||||||
app.HeartbeatService = service.NewHeartbeatService(app.WebsocketManager, app.DeviceStatusPool, app.DeviceRepo, app.Config)
|
app.HeartbeatService = service.NewHeartbeatService(app.WebsocketManager, app.DeviceStatusPool, app.DeviceRepo, app.Config)
|
||||||
|
|
||||||
// 初始化API组件
|
// 初始化API组件
|
||||||
app.API = api.NewAPI(app.Config, app.UserRepo, app.OperationHistoryRepo, app.DeviceControlRepo, app.DeviceRepo, app.WebsocketManager, app.HeartbeatService, app.DeviceStatusPool)
|
app.API = api.NewAPI(app.Config,
|
||||||
|
app.UserRepo,
|
||||||
|
app.OperationHistoryRepo,
|
||||||
|
app.DeviceControlRepo,
|
||||||
|
app.DeviceRepo,
|
||||||
|
app.FeedPlanRepo,
|
||||||
|
app.WebsocketManager,
|
||||||
|
app.HeartbeatService,
|
||||||
|
app.DeviceStatusPool,
|
||||||
|
)
|
||||||
|
|
||||||
// 初始化任务执行器组件(使用5个工作协程)
|
// 初始化任务执行器组件(使用5个工作协程)
|
||||||
app.TaskExecutor = task.NewExecutor(5)
|
app.TaskExecutor = task.NewExecutor(5)
|
||||||
|
|||||||
Reference in New Issue
Block a user