管理员后台: - 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>
64 lines
1.7 KiB
Go
64 lines
1.7 KiB
Go
// Package admin 提供管理员可用的系统配置接口
|
|
package admin
|
|
|
|
import (
|
|
"log"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/ssdomei232/goodBaby/api/response"
|
|
"github.com/ssdomei232/goodBaby/configs"
|
|
"github.com/ssdomei232/goodBaby/handler/scheduler"
|
|
)
|
|
|
|
// HandleGetConfig 返回当前可编辑的系统配置,以及一些只读的运行时信息
|
|
func HandleGetConfig(c *gin.Context) {
|
|
config, err := configs.GetConfig()
|
|
if err != nil {
|
|
response.ServerError(c, "读取配置失败")
|
|
return
|
|
}
|
|
|
|
response.OK(c, gin.H{
|
|
"config": config.Editable(),
|
|
// 只读信息,让管理员知道当前跑在什么环境上,但不能在这里改
|
|
"readonly": gin.H{
|
|
"listen_addr": config.ListenAddr,
|
|
"database_driver": config.DatabaseDriver,
|
|
},
|
|
})
|
|
}
|
|
|
|
// HandleUpdateConfig 更新可编辑的系统配置
|
|
func HandleUpdateConfig(c *gin.Context) {
|
|
var req configs.EditableConfig
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.BadRequest(c, "输入参数错误")
|
|
return
|
|
}
|
|
|
|
before, err := configs.GetConfig()
|
|
if err != nil {
|
|
response.ServerError(c, "读取配置失败")
|
|
return
|
|
}
|
|
|
|
updated, err := configs.ApplyEditable(req)
|
|
if err != nil {
|
|
// Validate 的错误可以直接展示给用户
|
|
response.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
|
|
// 检查间隔变了就重排定时任务,免得改完还要重启
|
|
if before.CheckIntervalMinutes != updated.CheckIntervalMinutes {
|
|
if err := scheduler.Reschedule(updated.CheckIntervalMinutes); err != nil {
|
|
log.Printf("重排定时任务失败: %v", err)
|
|
response.ServerError(c, "配置已保存,但定时任务重排失败,请重启服务")
|
|
return
|
|
}
|
|
log.Printf("检查间隔已更新为 %d 分钟", updated.CheckIntervalMinutes)
|
|
}
|
|
|
|
response.OK(c, updated.Editable())
|
|
}
|