148 lines
3.4 KiB
Go
148 lines
3.4 KiB
Go
package posterconfig
|
||
|
||
import (
|
||
"encoding/json"
|
||
"strings"
|
||
|
||
"hunliji-api/models"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
var (
|
||
db *gorm.DB
|
||
requireAdmin func(*gin.Context) bool
|
||
)
|
||
|
||
// Register 挂载海报配置路由:GET 公开,POST 需管理员
|
||
func Register(api *gin.RouterGroup, database *gorm.DB, adminGuard func(*gin.Context) bool) {
|
||
db = database
|
||
requireAdmin = adminGuard
|
||
api.GET("/poster/config", handleGetPosterConfig)
|
||
api.POST("/poster/config", handleSavePosterConfig)
|
||
}
|
||
|
||
// resolveSide 返回 "1"(男方)或 "2"(女方);无法识别返回空
|
||
func resolveSide(raw string) string {
|
||
v := strings.ToLower(strings.TrimSpace(raw))
|
||
switch v {
|
||
case "1", "male", "n", "m", "groom":
|
||
return "1"
|
||
case "2", "female", "nv", "f", "bride":
|
||
return "2"
|
||
default:
|
||
return ""
|
||
}
|
||
}
|
||
|
||
func isLegacyFlat(m map[string]interface{}) bool {
|
||
if m == nil {
|
||
return false
|
||
}
|
||
for _, k := range []string{"1", "2", "male", "female"} {
|
||
if _, ok := m[k]; ok {
|
||
return false
|
||
}
|
||
}
|
||
for _, k := range []string{"title", "lines", "heroImg", "sonName", "template"} {
|
||
if _, ok := m[k]; ok {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
func emptyObj() map[string]interface{} {
|
||
return map[string]interface{}{}
|
||
}
|
||
|
||
func asObject(v interface{}) map[string]interface{} {
|
||
if m, ok := v.(map[string]interface{}); ok {
|
||
return m
|
||
}
|
||
return emptyObj()
|
||
}
|
||
|
||
func takeSide(raw map[string]interface{}, keys ...string) map[string]interface{} {
|
||
for _, k := range keys {
|
||
if m := asObject(raw[k]); len(m) > 0 {
|
||
return m
|
||
}
|
||
}
|
||
return emptyObj()
|
||
}
|
||
|
||
// normalizeBundle 统一为 { "1", "2" };兼容旧 male/female 与扁平配置
|
||
func normalizeBundle(raw map[string]interface{}) map[string]interface{} {
|
||
if raw == nil {
|
||
raw = emptyObj()
|
||
}
|
||
out := map[string]interface{}{
|
||
"1": emptyObj(),
|
||
"2": emptyObj(),
|
||
}
|
||
if isLegacyFlat(raw) {
|
||
out["1"] = raw
|
||
return out
|
||
}
|
||
if m := takeSide(raw, "1", "male"); len(m) > 0 {
|
||
out["1"] = m
|
||
}
|
||
if f := takeSide(raw, "2", "female"); len(f) > 0 {
|
||
out["2"] = f
|
||
}
|
||
return out
|
||
}
|
||
|
||
func loadBundle() map[string]interface{} {
|
||
var config models.PosterConfig
|
||
if err := db.First(&config, 1).Error; err != nil {
|
||
return normalizeBundle(nil)
|
||
}
|
||
raw := strings.TrimSpace(config.ConfigData)
|
||
if raw == "" {
|
||
raw = "{}"
|
||
}
|
||
var parsed map[string]interface{}
|
||
if err := json.Unmarshal([]byte(raw), &parsed); err != nil {
|
||
return normalizeBundle(nil)
|
||
}
|
||
return normalizeBundle(parsed)
|
||
}
|
||
|
||
func handleGetPosterConfig(c *gin.Context) {
|
||
bundle := loadBundle()
|
||
side := resolveSide(c.Query("side"))
|
||
if side != "" {
|
||
c.JSON(200, gin.H{"code": 200, "data": bundle[side]})
|
||
return
|
||
}
|
||
c.JSON(200, gin.H{"code": 200, "data": bundle})
|
||
}
|
||
|
||
func handleSavePosterConfig(c *gin.Context) {
|
||
if !requireAdmin(c) {
|
||
return
|
||
}
|
||
var rawBody map[string]interface{}
|
||
if err := c.BindJSON(&rawBody); err != nil {
|
||
c.JSON(400, gin.H{"error": "无效的JSON数据"})
|
||
return
|
||
}
|
||
bundle := normalizeBundle(rawBody)
|
||
jsonBytes, err := json.Marshal(bundle)
|
||
if err != nil {
|
||
c.JSON(400, gin.H{"error": "无效的JSON数据"})
|
||
return
|
||
}
|
||
var config models.PosterConfig
|
||
db.Attrs(models.PosterConfig{ConfigData: "{}"}).FirstOrCreate(&config, models.PosterConfig{ID: 1})
|
||
config.ConfigData = string(jsonBytes)
|
||
if err := db.Save(&config).Error; err != nil {
|
||
c.JSON(500, gin.H{"error": "海报配置保存失败"})
|
||
return
|
||
}
|
||
c.JSON(200, gin.H{"code": 200, "msg": "海报配置保存成功", "data": bundle})
|
||
}
|