更新小程序配置,切换 API 地址为本地开发环境。新增会员详情页面的头像逻辑,确保用户信息展示一致性。优化多个页面的交互提示,提升用户体验。调整图标组件,更新图标映射以支持新样式。

This commit is contained in:
Alex-larget
2026-03-20 10:58:25 +08:00
parent 181f092402
commit e79152c80b
21 changed files with 658 additions and 158 deletions

View File

@@ -48,10 +48,15 @@ const KeyConfigAuditMode = "soul:config:audit-mode"
const KeyConfigCore = "soul:config:core"
const KeyConfigReadExtras = "soul:config:read-extras"
// Get 从 Redis 读取,未配置或失败返回 nil(调用方回退 DB
// Get 从 Redis 读取,未配置或失败时尝试内存备用;均失败返回 false(调用方回退 DB
func Get(ctx context.Context, key string, dest interface{}) bool {
client := redis.Client()
if client == nil {
// Redis 不可用,使用内存备用
if data, ok := memoryGet(key); ok && dest != nil && len(data) > 0 {
_ = json.Unmarshal(data, dest)
return true
}
return false
}
if ctx == nil {
@@ -61,6 +66,11 @@ func Get(ctx context.Context, key string, dest interface{}) bool {
defer cancel()
val, err := client.Get(ctx, key).Bytes()
if err != nil {
// Redis 超时/失败时尝试内存备用
if data, ok := memoryGet(key); ok && dest != nil && len(data) > 0 {
_ = json.Unmarshal(data, dest)
return true
}
return false
}
if dest != nil && len(val) > 0 {
@@ -69,10 +79,16 @@ func Get(ctx context.Context, key string, dest interface{}) bool {
return true
}
// Set 写入 Redis失败仅打日志不阻塞
// Set 写入 RedisRedis 不可用时写入内存备用;失败仅打日志不阻塞
func Set(ctx context.Context, key string, val interface{}, ttl time.Duration) {
data, err := json.Marshal(val)
if err != nil {
log.Printf("cache.Set marshal %s: %v", key, err)
return
}
client := redis.Client()
if client == nil {
memorySet(key, data, ttl)
return
}
if ctx == nil {
@@ -80,22 +96,20 @@ func Set(ctx context.Context, key string, val interface{}, ttl time.Duration) {
}
ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
defer cancel()
data, err := json.Marshal(val)
if err != nil {
log.Printf("cache.Set marshal %s: %v", key, err)
return
}
if err := client.Set(ctx, key, data, ttl).Err(); err != nil {
log.Printf("cache.Set %s: %v (非致命)", key, err)
log.Printf("cache.Set %s: %v (非致命),已写入内存备用", key, err)
memorySet(key, data, ttl)
}
}
// Del 删除 key失败仅打日志
// Del 删除 keyRedis 不可用时删除内存备用
func Del(ctx context.Context, key string) {
client := redis.Client()
if client == nil {
memoryDel(key)
return
}
memoryDel(key)
if ctx == nil {
ctx = context.Background()
}
@@ -106,12 +120,14 @@ func Del(ctx context.Context, key string) {
}
}
// DelPattern 按模式删除 key如 soul:book:chapters-by-part:*),用于批量失效
// DelPattern 按模式删除 key如 soul:book:chapters-by-part:*Redis 不可用时删除内存备
func DelPattern(ctx context.Context, pattern string) {
client := redis.Client()
if client == nil {
memoryDelPattern(pattern)
return
}
memoryDelPattern(pattern)
if ctx == nil {
ctx = context.Background()
}
@@ -183,10 +199,13 @@ func KeyChapterContent(mid int) string { return "soul:chapter:content:" + fmt.Sp
// ChapterContentTTL 章节正文 TTL后台更新时主动 Del
const ChapterContentTTL = 30 * time.Minute
// GetString 读取字符串(不经过 JSON适合大文本 content
// GetString 读取字符串(不经过 JSON适合大文本 contentRedis 不可用时尝试内存备用
func GetString(ctx context.Context, key string) (string, bool) {
client := redis.Client()
if client == nil {
if data, ok := memoryGet(key); ok {
return string(data), true
}
return "", false
}
if ctx == nil {
@@ -196,15 +215,19 @@ func GetString(ctx context.Context, key string) (string, bool) {
defer cancel()
val, err := client.Get(ctx, key).Result()
if err != nil {
if data, ok := memoryGet(key); ok {
return string(data), true
}
return "", false
}
return val, true
}
// SetString 写入字符串(不经过 JSON适合大文本 content
// SetString 写入字符串(不经过 JSON适合大文本 contentRedis 不可用时写入内存备用
func SetString(ctx context.Context, key string, val string, ttl time.Duration) {
client := redis.Client()
if client == nil {
memorySet(key, []byte(val), ttl)
return
}
if ctx == nil {
@@ -213,7 +236,8 @@ func SetString(ctx context.Context, key string, val string, ttl time.Duration) {
ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
defer cancel()
if err := client.Set(ctx, key, val, ttl).Err(); err != nil {
log.Printf("cache.SetString %s: %v (非致命)", key, err)
log.Printf("cache.SetString %s: %v (非致命),已写入内存备用", key, err)
memorySet(key, []byte(val), ttl)
}
}