更新小程序配置,切换 API 地址为本地开发环境。新增会员详情页面的头像逻辑,确保用户信息展示一致性。优化多个页面的交互提示,提升用户体验。调整图标组件,更新图标映射以支持新样式。
This commit is contained in:
50
soul-api/internal/cache/cache.go
vendored
50
soul-api/internal/cache/cache.go
vendored
@@ -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 写入 Redis,Redis 不可用时写入内存备用;失败仅打日志不阻塞
|
||||
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 删除 key,Redis 不可用时删除内存备用
|
||||
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,适合大文本 content),Redis 不可用时尝试内存备用
|
||||
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,适合大文本 content),Redis 不可用时写入内存备用
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user