管理员后台: - User 新增 IsAdmin,第一个注册的用户自动成为管理员; 老库升级时自动把最早注册的用户提升为管理员 - 新增 AdminMiddleware 与 /api/v1/admin/config 读写接口 - 可改开放注册、检查间隔、规则重试时长、日志保留条数,保存即生效 - 检查间隔改动后自动重排定时任务,为此把 cron 抽成 handler/scheduler - 监听地址、数据库、会话密钥等启动项不开放,接口只返回只读展示 - 设置页新增"系统配置"区块,仅管理员可见 PostgreSQL: - 新增 database_driver / database_dsn 配置,默认仍为 sqlite - postgres 用独立连接池(20/5/1h),sqlite 保持单连接避免写锁 - 启动时先 Ping,配置写错在启动阶段就报错而不是等到首次查询 - 支持 GOODBABY_DB_DRIVER / GOODBABY_DB_DSN 环境变量, 只给 DSN 时自动按 postgres 处理 文档: 新增 docs/database.md(含 compose 示例与切换说明),README 补充管理员与数据库章节 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
77 lines
1.5 KiB
Go
77 lines
1.5 KiB
Go
// Package scheduler 管理定时检查任务,支持运行时调整间隔
|
|
package scheduler
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/robfig/cron/v3"
|
|
"github.com/ssdomei232/goodBaby/handler/checker"
|
|
)
|
|
|
|
var (
|
|
mu sync.Mutex
|
|
runner *cron.Cron
|
|
entryID cron.EntryID
|
|
)
|
|
|
|
// Start 启动定时检查,interval 单位为分钟
|
|
func Start(intervalMinutes int) error {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
|
|
if runner != nil {
|
|
return fmt.Errorf("定时任务已经启动")
|
|
}
|
|
|
|
runner = cron.New()
|
|
id, err := runner.AddFunc(spec(intervalMinutes), checker.CheckTimers)
|
|
if err != nil {
|
|
runner = nil
|
|
return fmt.Errorf("注册定时任务失败: %w", err)
|
|
}
|
|
|
|
entryID = id
|
|
runner.Start()
|
|
return nil
|
|
}
|
|
|
|
// Reschedule 用新的间隔重排定时任务,管理员改配置后调用
|
|
func Reschedule(intervalMinutes int) error {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
|
|
if runner == nil {
|
|
return fmt.Errorf("定时任务尚未启动")
|
|
}
|
|
|
|
// cron 不支持原地改周期,只能撤掉旧的再加一个
|
|
runner.Remove(entryID)
|
|
id, err := runner.AddFunc(spec(intervalMinutes), checker.CheckTimers)
|
|
if err != nil {
|
|
return fmt.Errorf("注册定时任务失败: %w", err)
|
|
}
|
|
|
|
entryID = id
|
|
return nil
|
|
}
|
|
|
|
// Stop 停止定时任务,等待正在执行的任务结束
|
|
func Stop() {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
|
|
if runner == nil {
|
|
return
|
|
}
|
|
<-runner.Stop().Done()
|
|
runner = nil
|
|
}
|
|
|
|
func spec(intervalMinutes int) string {
|
|
if intervalMinutes <= 0 {
|
|
intervalMinutes = 10
|
|
}
|
|
return fmt.Sprintf("@every %dm", intervalMinutes)
|
|
}
|