feat: 小程序阅读记录与资料链路、管理端用户规则、API/VIP/推荐与运营脚本
- miniprogram: reading-records、imageUrl/mpNavigate、多页资料与 VIP 展示调整 - soul-admin: Users/Settings/UserDetailModal、dist 构建产物更新 - soul-api: user/vip/referral/ckb/db、MBTI 头像管理、user_rule_completion、迁移 SQL - .cursor: karuo-party 与飞书文档;.gitignore 忽略 .tmp_skill_bundle Made-with: Cursor
This commit is contained in:
88
soul-api/internal/handler/admin_mbti_avatars.go
Normal file
88
soul-api/internal/handler/admin_mbti_avatars.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"soul-api/internal/database"
|
||||
"soul-api/internal/model"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const mbtiAvatarsConfigKey = "mbti_avatars"
|
||||
const mbtiAvatarsDescription = "MBTI 16型人格头像映射"
|
||||
|
||||
// AdminMbtiAvatarsGet GET /api/admin/mbti-avatars 读取 MBTI 头像映射(system_config.mbti_avatars)
|
||||
func AdminMbtiAvatarsGet(c *gin.Context) {
|
||||
db := database.DB()
|
||||
var row model.SystemConfig
|
||||
err := db.Where("config_key = ?", mbtiAvatarsConfigKey).First(&row).Error
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
c.JSON(http.StatusOK, gin.H{"success": true, "avatars": map[string]string{}})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"success": false, "error": "读取配置失败: " + err.Error()})
|
||||
return
|
||||
}
|
||||
out := make(map[string]string)
|
||||
if len(row.ConfigValue) > 0 {
|
||||
if uerr := json.Unmarshal(row.ConfigValue, &out); uerr != nil {
|
||||
c.JSON(http.StatusOK, gin.H{"success": false, "error": "配置 JSON 无效: " + uerr.Error()})
|
||||
return
|
||||
}
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"success": true, "avatars": out})
|
||||
}
|
||||
|
||||
// AdminMbtiAvatarsPost POST /api/admin/mbti-avatars 保存 MBTI 头像映射(upsert)
|
||||
func AdminMbtiAvatarsPost(c *gin.Context) {
|
||||
var body struct {
|
||||
Avatars map[string]string `json:"avatars"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{"success": false, "error": "请求体无效"})
|
||||
return
|
||||
}
|
||||
avatars := body.Avatars
|
||||
if avatars == nil {
|
||||
avatars = map[string]string{}
|
||||
}
|
||||
valBytes, err := json.Marshal(avatars)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{"success": false, "error": "序列化失败: " + err.Error()})
|
||||
return
|
||||
}
|
||||
db := database.DB()
|
||||
desc := mbtiAvatarsDescription
|
||||
var row model.SystemConfig
|
||||
err = db.Where("config_key = ?", mbtiAvatarsConfigKey).First(&row).Error
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
row = model.SystemConfig{
|
||||
ConfigKey: mbtiAvatarsConfigKey,
|
||||
ConfigValue: valBytes,
|
||||
Description: &desc,
|
||||
}
|
||||
if cerr := db.Create(&row).Error; cerr != nil {
|
||||
c.JSON(http.StatusOK, gin.H{"success": false, "error": "保存失败: " + cerr.Error()})
|
||||
return
|
||||
}
|
||||
} else {
|
||||
c.JSON(http.StatusOK, gin.H{"success": false, "error": "查询配置失败: " + err.Error()})
|
||||
return
|
||||
}
|
||||
} else {
|
||||
row.ConfigValue = valBytes
|
||||
row.Description = &desc
|
||||
if serr := db.Save(&row).Error; serr != nil {
|
||||
c.JSON(http.StatusOK, gin.H{"success": false, "error": "保存失败: " + serr.Error()})
|
||||
return
|
||||
}
|
||||
}
|
||||
_mbtiAvatarCacheTs = 0
|
||||
c.JSON(http.StatusOK, gin.H{"success": true, "message": "MBTI 头像映射已保存"})
|
||||
}
|
||||
Reference in New Issue
Block a user