152 lines
3.6 KiB
Go
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)})
|
|
}
|