迁移配置文件, 实现从json文件中读取原材料营养预设值, 并自动写入数据库

This commit is contained in:
2025-11-19 19:31:51 +08:00
parent a1be06854f
commit a74ab4e5e7
9 changed files with 1991 additions and 186 deletions

View File

@@ -14,9 +14,10 @@ import (
// Application 是整个应用的核心,封装了所有组件和生命周期。
type Application struct {
Config *config.Config
Ctx context.Context
API *api.API
cfgPath string
Config *config.Config
Ctx context.Context
API *api.API
Infra *Infrastructure
Domain *DomainServices
@@ -68,12 +69,13 @@ func NewApplication(configPath string) (*Application, error) {
// 4. 组装 Application 对象
app := &Application{
Config: cfg,
Ctx: selfCtx,
API: apiServer,
Infra: infra,
Domain: domain,
App: appServices,
cfgPath: configPath,
Config: cfg,
Ctx: selfCtx,
API: apiServer,
Infra: infra,
Domain: domain,
App: appServices,
}
return app, nil
@@ -90,7 +92,7 @@ func (app *Application) Start() error {
}
// 2. 初始化应用状态 (清理、刷新任务等)
if err := app.initializeState(startCtx); err != nil {
if err := app.initializeState(startCtx, app.cfgPath); err != nil {
return fmt.Errorf("初始化应用状态失败: %w", err)
}

View File

@@ -3,8 +3,10 @@ package core
import (
"context"
"fmt"
"path/filepath"
"git.huangwc.com/pig/pig-farm-controller/internal/domain/task"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/database"
"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"
@@ -12,27 +14,35 @@ import (
// initializeState 在应用启动时准备其初始数据状态。
// 它遵循一个严格的顺序:清理 -> 更新 -> 刷新,以确保数据的一致性和正确性。
func (app *Application) initializeState(ctx context.Context) error {
func (app *Application) initializeState(ctx context.Context, cfgPath string) error {
appCtx, logger := logs.Trace(ctx, app.Ctx, "InitializeState")
// 1. 清理所有上次运行时遗留的待执行任务和相关日志。
// 1. 播种预设数据
logger.Info("开始播种预设数据...")
presetDir := filepath.Join(filepath.Dir(cfgPath), "presets-data")
if err := database.SeedFromPreset(appCtx, app.Infra.storage.GetDB(appCtx), presetDir); err != nil {
return fmt.Errorf("预设数据播种失败: %w", err)
}
logger.Info("预设数据播种成功。")
// 2. 清理所有上次运行时遗留的待执行任务和相关日志。
// 这一步必须在任何可能修改计划结构的操作之前执行,以避免外键约束冲突。
if err := app.cleanupStaleTasksAndLogs(appCtx); err != nil {
return fmt.Errorf("清理过期的任务及日志失败: %w", err)
}
// 2. 清理待采集任务 (非致命错误)。
// 3. 清理待采集任务 (非致命错误)。
if err := app.initializePendingCollections(appCtx); err != nil {
logger.Errorw("清理待采集任务时发生非致命错误", "error", err)
}
// 3. 初始化并更新系统计划。
// 4. 初始化并更新系统计划。
// 此时,所有旧的待执行任务已被清除,可以安全地更新计划结构。
if err := app.initializeSystemPlans(ctx); err != nil {
return fmt.Errorf("初始化预定义系统计划失败: %w", err)
}
// 4. 最后,根据最新的计划状态,统一刷新所有计划的触发器。
// 5. 最后,根据最新的计划状态,统一刷新所有计划的触发器。
// 这一步确保了新创建或更新的系统计划能够被正确地调度。
logger.Info("正在刷新所有计划的触发器...")
if err := app.Domain.planService.RefreshPlanTriggers(appCtx); err != nil {