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:
@@ -1,6 +1,7 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -345,6 +346,9 @@ func formatVipMember(db *gorm.DB, u *model.User, isVip bool) gin.H {
|
||||
if avatar == "" {
|
||||
avatar = getUrlValue(u.VipAvatar)
|
||||
}
|
||||
if avatar == "" && u.Mbti != nil && *u.Mbti != "" {
|
||||
avatar = getMbtiAvatar(db, strings.ToUpper(strings.TrimSpace(*u.Mbti)))
|
||||
}
|
||||
avatar = resolveAvatarURL(avatar)
|
||||
project := getStringValue(u.VipProject)
|
||||
if project == "" {
|
||||
@@ -420,3 +424,24 @@ func formatVipMember(db *gorm.DB, u *model.User, isVip bool) gin.H {
|
||||
func parseInt(s string) (int, error) {
|
||||
return strconv.Atoi(s)
|
||||
}
|
||||
|
||||
var _mbtiAvatarCache map[string]string
|
||||
var _mbtiAvatarCacheTs int64
|
||||
|
||||
func getMbtiAvatar(db *gorm.DB, mbti string) string {
|
||||
now := time.Now().Unix()
|
||||
if _mbtiAvatarCache != nil && now-_mbtiAvatarCacheTs < 300 {
|
||||
return _mbtiAvatarCache[mbti]
|
||||
}
|
||||
var cfg model.SystemConfig
|
||||
if err := db.Where("config_key = ?", "mbti_avatars").First(&cfg).Error; err != nil {
|
||||
return ""
|
||||
}
|
||||
m := make(map[string]string)
|
||||
if err := json.Unmarshal([]byte(cfg.ConfigValue), &m); err != nil {
|
||||
return ""
|
||||
}
|
||||
_mbtiAvatarCache = m
|
||||
_mbtiAvatarCacheTs = now
|
||||
return m[mbti]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user