# 缓存清理: banner / 字典 / 精选评价 admin 改完小程序立即生效(前端无感)

> **服务**: hl-user-service (8081) + hl-order-service-v2 (8084) + hl-common-redis
> **PR**: #1855 + #1858
> **Issue**: #1854 + #1856(根因 + follow-up 批量修)
> **日期**: 2026-05-08
> **影响范围**: 纯后端缓存清理逻辑,**前端不需要改代码**

---

## ⚠️ 给前端的话

**这 2 个 PR 都是后端缓存 bug 修复,前端 0 改动**。但用户体验有提升:

| 模块 | 修前 | 修后 |
|------|------|------|
| 小程序首页轮播图 | admin 改完最长 5 分钟才生效 | **admin 改完立即生效** |
| 字典(下拉选项 / linkType label 等)| admin 改完 5 分钟内 C 端看到旧选项 | **立即生效** |
| 首页/设计师页精选评价 | 审核员通过/驳回评价后 ~11 分钟不刷新 | **立即生效** |

如果前端测试时遇到 admin 改完依然要等几分钟才生效的同类问题,**可能还有别的 service 漏改**,直接告诉 wx 起 follow-up 工单。

---

## 一、根因(prod 实测)

`MpCacheEvict.deleteByPrefix(prefix)` 内部强行加 `mp:` 前缀 SCAN(`mp:{prefix}*`),但下面 3 个 service 自己用 `depsManager.putWithDeps(KEY, ...)` 写入的 cache key **不带 `mp:` 前缀**,导致 evict 完全 SCAN 不到自己的 key。

兜底的 `depsManager.invalidateSource(...)` 也救不了 — prod 实测反向索引 SET 实际为空(总依赖=0)。结果 admin 改完只能等 cache 自然 TTL 过期。

---

## 二、修复

3 处 service 在 `cacheEvictAfterCommit.schedule(...)` lambda 加显式 `redisTemplate.delete(KEY)` 兜底:

| Service | 文件 | KEY |
|---|---|---|
| BannerService | `hl-user-service` | `banner:active:list:v3` |
| SysDictService(6 处)| `hl-user-service` | `cache:dict:data:{dictType}` |
| FeaturedReviewCache | `hl-order-service-v2` | `review:featured:limit:*`(SCAN 自删)|

配套加固:`MpCacheEvict.java` 类 javadoc 加红字警告,防止后续新代码继续踩同坑。

---

## 三、变更接口清单

**无 API 变更**。所有 admin 写接口、所有 mp 读接口路径/参数/响应**完全不变**。仅缓存清理逻辑变化。

---

## 四、后续 follow-up(本次不动)

- **#1860 (P1)**: `DependencyAwareCacheManager.putWithDeps` 反向索引 SADD 失效根因排查
- **#1861 (P2)**: D5 删除 MpCacheEvict 重构,全部走 invalidateSource 单一路径

---

## 五、测试

- BannerServiceTest 31/31 全绿
- SysDictServiceTest 27/27 全绿
- FeaturedReviewCacheTest 11/11 全绿
- 共 69/69 PASSED
