Files
hunli/hunliji-api/configsection/section.go
2026-08-04 12:54:33 +08:00

152 lines
3.6 KiB
Go

package configsection
import (
"encoding/json"
"strings"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
type templateConfig struct {
ID uint `gorm:"primaryKey"`
ConfigData string `gorm:"type:json;column:config_data;not null"`
}
func (templateConfig) TableName() string { return "template_configs" }
var (
db *gorm.DB
requireAdmin func(*gin.Context) bool
)
var configSectionKeys = map[string][]string{
"basic": {
"groom", "bride", "date", "lunar", "calendarDate", "hotel", "address",
"heroImg", "heroImgResized", "heroImgResizedMeta",
"endImg", "endImgResized", "endImgResizedMeta",
},
"copy": {
"formalText1", "formalText2", "formalPageHeight",
},
"visual": {
"introExitEffect", "scrollMode", "freeScrollInterval", "pageSwitchDuration", "firstScreenDuration",
"petalEnabled", "bubbleEnabled", "introEnabled", "danmakuEnabled", "danmakuShowTime", "nineGridAnimate",
},
"music": {
"musicList", "activeMusicUrl", "musicRandomEnabled",
"musicCacheEnabled", "musicCacheHours",
},
"photos": {
"photoPages",
},
"schedule": {
"schedule",
},
}
// Register 由 main 入口调用:注入依赖并挂载分段配置路由
func Register(api *gin.RouterGroup, database *gorm.DB, adminGuard func(*gin.Context) bool) {
db = database
requireAdmin = adminGuard
api.GET("/config/section", handleGetConfigSection)
api.POST("/config/section", handleSaveConfigSection)
}
func loadConfigMap() (map[string]interface{}, error) {
var config templateConfig
if err := db.First(&config, 1).Error; err != nil {
return map[string]interface{}{}, nil
}
raw := strings.TrimSpace(config.ConfigData)
if raw == "" {
raw = "{}"
}
var m map[string]interface{}
if err := json.Unmarshal([]byte(raw), &m); err != nil {
return nil, err
}
if m == nil {
m = map[string]interface{}{}
}
return m, nil
}
func saveConfigMap(m map[string]interface{}) error {
jsonBytes, err := json.Marshal(m)
if err != nil {
return err
}
var config templateConfig
db.Attrs(templateConfig{ConfigData: "{}"}).FirstOrCreate(&config, templateConfig{ID: 1})
config.ConfigData = string(jsonBytes)
return db.Save(&config).Error
}
func pickSection(full map[string]interface{}, keys []string) map[string]interface{} {
out := make(map[string]interface{}, len(keys))
for _, k := range keys {
if v, ok := full[k]; ok {
out[k] = v
}
}
return out
}
func handleGetConfigSection(c *gin.Context) {
if !requireAdmin(c) {
return
}
section := strings.TrimSpace(c.Query("section"))
keys, ok := configSectionKeys[section]
if !ok {
c.JSON(400, gin.H{"error": "未知的 section"})
return
}
full, err := loadConfigMap()
if err != nil {
c.JSON(500, gin.H{"error": "读取配置失败"})
return
}
c.JSON(200, gin.H{"code": 200, "data": pickSection(full, keys)})
}
func handleSaveConfigSection(c *gin.Context) {
if !requireAdmin(c) {
return
}
var body struct {
Section string `json:"section"`
Data map[string]interface{} `json:"data"`
}
if err := c.ShouldBindJSON(&body); err != nil {
c.JSON(400, gin.H{"error": "参数错误"})
return
}
section := strings.TrimSpace(body.Section)
keys, ok := configSectionKeys[section]
if !ok {
c.JSON(400, gin.H{"error": "未知的 section"})
return
}
if body.Data == nil {
body.Data = map[string]interface{}{}
}
full, err := loadConfigMap()
if err != nil {
c.JSON(500, gin.H{"error": "读取配置失败"})
return
}
for _, k := range keys {
if v, ok := body.Data[k]; ok {
full[k] = v
}
}
if err := saveConfigMap(full); err != nil {
c.JSON(500, gin.H{"error": "保存配置失败"})
return
}
c.JSON(200, gin.H{"code": 200, "msg": "配置段已保存", "data": pickSection(full, keys)})
}