1. 增加任务调度器配置文件

2. 创建/更新计划会自动处理触发器
This commit is contained in:
2025-09-17 23:01:15 +08:00
parent f7a5e4737d
commit 810049d62e
7 changed files with 90 additions and 42 deletions

View File

@@ -19,6 +19,7 @@ import (
"git.huangwc.com/pig/pig-farm-controller/internal/app/controller/device"
"git.huangwc.com/pig/pig-farm-controller/internal/app/controller/plan"
"git.huangwc.com/pig/pig-farm-controller/internal/app/controller/user"
"git.huangwc.com/pig/pig-farm-controller/internal/app/service/task"
"git.huangwc.com/pig/pig-farm-controller/internal/app/service/token"
"git.huangwc.com/pig/pig-farm-controller/internal/app/service/transport"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/config"
@@ -33,21 +34,29 @@ import (
// API 结构体定义了 HTTP 服务器及其依赖
type API struct {
engine *gin.Engine // Gin 引擎实例,用于处理 HTTP 请求
logger *logs.Logger // 日志记录器,用于输出日志信息
userRepo repository.UserRepository // 用户数据仓库接口,用于用户数据操作
tokenService token.TokenService // Token 服务接口,用于 JWT token 的生成和解析
httpServer *http.Server // 标准库的 HTTP 服务器实例,用于启动和停止服务
config config.ServerConfig // API 服务器的配置,使用 infra/config 包中的 ServerConfig
userController *user.Controller // 用户控制器实例
deviceController *device.Controller // 设备控制器实例
planController *plan.Controller // 计划控制器实例
listenHandler transport.ListenHandler // 设备上行事件监听器
engine *gin.Engine // Gin 引擎实例,用于处理 HTTP 请求
logger *logs.Logger // 日志记录器,用于输出日志信息
userRepo repository.UserRepository // 用户数据仓库接口,用于用户数据操作
tokenService token.TokenService // Token 服务接口,用于 JWT token 的生成和解析
httpServer *http.Server // 标准库的 HTTP 服务器实例,用于启动和停止服务
config config.ServerConfig // API 服务器的配置,使用 infra/config 包中的 ServerConfig
userController *user.Controller // 用户控制器实例
deviceController *device.Controller // 设备控制器实例
planController *plan.Controller // 计划控制器实例
listenHandler transport.ListenHandler // 设备上行事件监听器
analysisTaskManager *task.AnalysisPlanTaskManager // 计划触发器管理器实例
}
// NewAPI 创建并返回一个新的 API 实例
// 负责初始化 Gin 引擎、设置全局中间件,并注入所有必要的依赖。
func NewAPI(cfg config.ServerConfig, logger *logs.Logger, userRepo repository.UserRepository, deviceRepository repository.DeviceRepository, planRepository repository.PlanRepository, tokenService token.TokenService, listenHandler transport.ListenHandler) *API {
func NewAPI(cfg config.ServerConfig,
logger *logs.Logger,
userRepo repository.UserRepository,
deviceRepository repository.DeviceRepository,
planRepository repository.PlanRepository,
tokenService token.TokenService,
listenHandler transport.ListenHandler,
analysisTaskManager *task.AnalysisPlanTaskManager) *API {
// 设置 Gin 模式,例如 gin.ReleaseMode (生产模式) 或 gin.DebugMode (开发模式)
// 从配置中获取 Gin 模式
gin.SetMode(cfg.Mode)
@@ -73,7 +82,7 @@ func NewAPI(cfg config.ServerConfig, logger *logs.Logger, userRepo repository.Us
// 在 NewAPI 中初始化设备控制器,并将其作为 API 结构体的成员
deviceController: device.NewController(deviceRepository, logger),
// 在 NewAPI 中初始化计划控制器,并将其作为 API 结构体的成员
planController: plan.NewController(logger, planRepository),
planController: plan.NewController(logger, planRepository, analysisTaskManager),
}
api.setupRoutes() // 设置所有路由

View File

@@ -5,6 +5,7 @@ import (
"strconv"
"git.huangwc.com/pig/pig-farm-controller/internal/app/controller"
task "git.huangwc.com/pig/pig-farm-controller/internal/app/service/task"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
@@ -74,7 +75,7 @@ type TaskRequest struct {
// TaskResponse 定义任务响应结构体
type TaskResponse struct {
ID uint `json:"id" example:"1"`
ID int `json:"id" example:"1"`
PlanID uint `json:"plan_id" example:"1"`
Name string `json:"name" example:"打开风扇"`
Description string `json:"description" example:"打开1号风扇"`
@@ -87,15 +88,17 @@ type TaskResponse struct {
// Controller 定义了计划相关的控制器
type Controller struct {
logger *logs.Logger
planRepo repository.PlanRepository
logger *logs.Logger
planRepo repository.PlanRepository
analysisPlanTaskManager *task.AnalysisPlanTaskManager
}
// NewController 创建一个新的 Controller 实例
func NewController(logger *logs.Logger, planRepo repository.PlanRepository) *Controller {
func NewController(logger *logs.Logger, planRepo repository.PlanRepository, analysisPlanTaskManager *task.AnalysisPlanTaskManager) *Controller {
return &Controller{
logger: logger,
planRepo: planRepo,
logger: logger,
planRepo: planRepo,
analysisPlanTaskManager: analysisPlanTaskManager,
}
}
@@ -131,6 +134,12 @@ func (c *Controller) CreatePlan(ctx *gin.Context) {
return
}
// 创建成功后,调用 manager 创建或更新触发器
if err := c.analysisPlanTaskManager.CreateOrUpdateTrigger(ctx, planToCreate.ID); err != nil {
// 这是一个非阻塞性错误,我们只记录日志,因为主流程(创建计划)已经成功
c.logger.Errorf("为新创建的计划 %d 创建触发器失败: %v", planToCreate.ID, err)
}
// 使用已有的转换函数将创建后的模型转换为响应对象
resp := PlanToResponse(planToCreate)
@@ -261,6 +270,12 @@ func (c *Controller) UpdatePlan(ctx *gin.Context) {
return
}
// 更新成功后,调用 manager 创建或更新触发器
if err := c.analysisPlanTaskManager.CreateOrUpdateTrigger(ctx, planToUpdate.ID); err != nil {
// 这是一个非阻塞性错误,我们只记录日志
c.logger.Errorf("为更新后的计划 %d 更新触发器失败: %v", planToUpdate.ID, err)
}
// 6. 获取更新后的完整计划用于响应
updatedPlan, err := c.planRepo.GetPlanByID(uint(id))
if err != nil {