From c22725601524c798719cb6b9701553d2db33802b Mon Sep 17 00:00:00 2001 From: zpc Date: Wed, 1 Apr 2026 18:28:28 +0800 Subject: [PATCH] feat(liveforum): add WebAPI Redis cache management for streamer flower counts - Add WebApiCache Redis client instance to RedisServer for separate cache storage - Configure WebApiCache in appsettings.json with dedicated database (db=2) - Add ClearAllFlowerCache() method to IT_StreamersService interface and implementation - Add clear-flower-cache endpoint in T_StreamersController with permission and logging - Update flower cache operations to use WebApiCache instead of main Cache instance - Migrate existing cache clear logic in UpdateStreamer and BatchSetFlowerCount to use WebApiCache - Add clearFlowerCache API function to frontend tstreamers.js - Add clear cache button to tstreamers.vue UI for manual cache management - Improves cache isolation between admin and WebAPI services, enabling independent cache lifecycle management --- .../Infrastructure/Cache/RedisServer.cs | 6 ++++ .../Liveforum/T_StreamersController.cs | 20 +++++++++++ .../ZR.Admin.WebApi/appsettings.json | 3 +- .../ILiveforumService/IT_StreamersService.cs | 6 ++++ .../Liveforum/T_StreamersService.cs | 34 +++++++++++++++---- .../ZR.Vue/src/api/liveforum/tstreamers.js | 10 ++++++ .../ZR.Vue/src/views/liveforum/tstreamers.vue | 24 ++++++++++++- 7 files changed, 94 insertions(+), 9 deletions(-) diff --git a/server/admin/ZrAdminNetCore/Infrastructure/Cache/RedisServer.cs b/server/admin/ZrAdminNetCore/Infrastructure/Cache/RedisServer.cs index aa3312c..02e171f 100644 --- a/server/admin/ZrAdminNetCore/Infrastructure/Cache/RedisServer.cs +++ b/server/admin/ZrAdminNetCore/Infrastructure/Cache/RedisServer.cs @@ -7,11 +7,17 @@ namespace ZR.Common.Cache { public static CSRedisClient Cache; public static CSRedisClient Session; + public static CSRedisClient WebApiCache; public static void Initalize() { Cache = new CSRedisClient(AppSettings.GetConfig("RedisServer:Cache")); Session = new CSRedisClient(AppSettings.GetConfig("RedisServer:Session")); + var webApiCacheConfig = AppSettings.GetConfig("RedisServer:WebApiCache"); + if (!string.IsNullOrEmpty(webApiCacheConfig)) + { + WebApiCache = new CSRedisClient(webApiCacheConfig); + } } } } diff --git a/server/admin/ZrAdminNetCore/ZR.Admin.WebApi/Controllers/Liveforum/T_StreamersController.cs b/server/admin/ZrAdminNetCore/ZR.Admin.WebApi/Controllers/Liveforum/T_StreamersController.cs index e700e75..b4891d2 100644 --- a/server/admin/ZrAdminNetCore/ZR.Admin.WebApi/Controllers/Liveforum/T_StreamersController.cs +++ b/server/admin/ZrAdminNetCore/ZR.Admin.WebApi/Controllers/Liveforum/T_StreamersController.cs @@ -168,5 +168,25 @@ namespace ZR.Admin.WebApi.Controllers.Liveforum return ToResponse(result); } + /// + /// 清空所有主播送花缓存 + /// + /// + [HttpPost("clear-flower-cache")] + [ActionPermissionFilter(Permission = "tstreamers:edit")] + [Log(Title = "清空送花缓存", BusinessType = BusinessType.OTHER)] + public IActionResult ClearFlowerCache() + { + try + { + var count = _T_StreamersService.ClearAllFlowerCache(); + return SUCCESS(new { clearedCount = count, message = $"成功清除 {count} 个送花缓存" }); + } + catch (Exception ex) + { + throw new CustomException(ResultCode.CUSTOM_ERROR, $"清除缓存失败:{ex.Message}"); + } + } + } } \ No newline at end of file diff --git a/server/admin/ZrAdminNetCore/ZR.Admin.WebApi/appsettings.json b/server/admin/ZrAdminNetCore/ZR.Admin.WebApi/appsettings.json index c94c221..a95ff36 100644 --- a/server/admin/ZrAdminNetCore/ZR.Admin.WebApi/appsettings.json +++ b/server/admin/ZrAdminNetCore/ZR.Admin.WebApi/appsettings.json @@ -109,7 +109,8 @@ "open": 1, //是否启用redis "dbCache": false, //数据库是否使用Redis缓存,如果启用open要为1 "Cache": "192.168.195.15:6379,defaultDatabase=6,poolsize=50,ssl=false,writeBuffer=10240,prefix=cache:", - "Session": "192.168.195.15:6379,defaultDatabase=7,poolsize=50,ssl=false,writeBuffer=10240,prefix=session:" + "Session": "192.168.195.15:6379,defaultDatabase=7,poolsize=50,ssl=false,writeBuffer=10240,prefix=session:", + "WebApiCache": "192.168.195.15:6379,defaultDatabase=2,poolsize=10,ssl=false,writeBuffer=10240" }, //验证码配置 "CaptchaOptions": { diff --git a/server/admin/ZrAdminNetCore/ZR.Service/Liveforum/ILiveforumService/IT_StreamersService.cs b/server/admin/ZrAdminNetCore/ZR.Service/Liveforum/ILiveforumService/IT_StreamersService.cs index db4946b..0e945bd 100644 --- a/server/admin/ZrAdminNetCore/ZR.Service/Liveforum/ILiveforumService/IT_StreamersService.cs +++ b/server/admin/ZrAdminNetCore/ZR.Service/Liveforum/ILiveforumService/IT_StreamersService.cs @@ -39,5 +39,11 @@ namespace ZR.Service.Liveforum.ILiveforumService /// 是否设置所有主播 /// int BatchSetFlowerCount(int[]? ids, int minFlowerCount, int maxFlowerCount, bool setAll = false); + + /// + /// 清空所有主播的送花缓存 + /// + /// 清除的缓存key数量 + int ClearAllFlowerCache(); } } diff --git a/server/admin/ZrAdminNetCore/ZR.Service/Liveforum/T_StreamersService.cs b/server/admin/ZrAdminNetCore/ZR.Service/Liveforum/T_StreamersService.cs index bc7ecd9..eb7de4d 100644 --- a/server/admin/ZrAdminNetCore/ZR.Service/Liveforum/T_StreamersService.cs +++ b/server/admin/ZrAdminNetCore/ZR.Service/Liveforum/T_StreamersService.cs @@ -75,14 +75,14 @@ namespace ZR.Service.Liveforum { var result = Update(model, true); - // 清除该主播的Redis花数缓存 + // 清除该主播在WebAPI Redis中的花数缓存 try { - RedisServer.Cache.Del($"flower_count:Streamer:{model.Id}"); + RedisServer.WebApiCache?.Del($"flower_count:Streamer:{model.Id}"); } catch (Exception ex) { - NLog.LogManager.GetCurrentClassLogger().Warn(ex, "清除Redis花数缓存失败, StreamerId: {0}", model.Id); + NLog.LogManager.GetCurrentClassLogger().Warn(ex, "清除WebAPI Redis花数缓存失败, StreamerId: {0}", model.Id); } return result; @@ -139,24 +139,44 @@ namespace ZR.Service.Liveforum .UpdateColumns(it => new { it.FlowerCount, it.UpdatedAt }) .ExecuteCommand(); - // 清除Redis中对应主播的花数缓存,确保WebAPI读取最新数据 + // 清除WebAPI Redis中对应主播的花数缓存 try { foreach (var streamer in streamers) { var cacheKey = $"flower_count:Streamer:{streamer.Id}"; - RedisServer.Cache.Del(cacheKey); + RedisServer.WebApiCache?.Del(cacheKey); } } catch (Exception ex) { - // Redis清除失败不影响主流程,缓存会在24小时后自动过期 - NLog.LogManager.GetCurrentClassLogger().Warn(ex, "清除Redis花数缓存失败"); + NLog.LogManager.GetCurrentClassLogger().Warn(ex, "清除WebAPI Redis花数缓存失败"); } return result; } + /// + /// 清空所有主播的送花缓存(WebAPI Redis) + /// + /// 清除的缓存key数量 + public int ClearAllFlowerCache() + { + if (RedisServer.WebApiCache == null) + { + throw new Exception("WebAPI Redis未配置,请检查appsettings.json中的RedisServer:WebApiCache配置"); + } + + var keys = RedisServer.WebApiCache.Keys("flower_count:Streamer:*"); + if (keys == null || keys.Length == 0) + { + return 0; + } + + RedisServer.WebApiCache.Del(keys); + return keys.Length; + } + /// /// 查询导出表达式 /// diff --git a/server/admin/ZrAdminNetCore/ZR.Vue/src/api/liveforum/tstreamers.js b/server/admin/ZrAdminNetCore/ZR.Vue/src/api/liveforum/tstreamers.js index cf5b786..2616130 100644 --- a/server/admin/ZrAdminNetCore/ZR.Vue/src/api/liveforum/tstreamers.js +++ b/server/admin/ZrAdminNetCore/ZR.Vue/src/api/liveforum/tstreamers.js @@ -91,3 +91,13 @@ export function batchSetFlowerCount(data) { data: data }) } + +/** + * 清空所有主播送花缓存 + */ +export function clearFlowerCache() { + return request({ + url: 'liveforum/tstreamers/clear-flower-cache', + method: 'POST' + }) +} diff --git a/server/admin/ZrAdminNetCore/ZR.Vue/src/views/liveforum/tstreamers.vue b/server/admin/ZrAdminNetCore/ZR.Vue/src/views/liveforum/tstreamers.vue index 19f0949..8d6613f 100644 --- a/server/admin/ZrAdminNetCore/ZR.Vue/src/views/liveforum/tstreamers.vue +++ b/server/admin/ZrAdminNetCore/ZR.Vue/src/views/liveforum/tstreamers.vue @@ -53,6 +53,11 @@ 批量设置送花数量 + + + 清空送花缓存 + + @@ -291,7 +296,7 @@