修改菜单权限刷新产品菜单缓存失效修复

This commit is contained in:
gaoqr
2026-08-13 15:21:26 +08:00
parent c2eb6c4bd2
commit 4f0923ac25
4 changed files with 42 additions and 30 deletions
@@ -117,10 +117,9 @@ public class RedisKeyConstants {
public static final String SMS_CAPTCHA_VERIFICATION_LIMIT = "sms_captcha_verification_limit:%s";
/**
* 套餐下的权限菜单id:12h代表key的ttl为12小时
* !!!!注意同步修改OrganRedisCacheManager中的key字符串
* 产品套餐下的权限菜单 id12h 代表 key 的 ttl 为 12 小时
*/
public static final String TENANT_PACKAGE_MENU_IDS = "tenant_package_menu_ids#12h";
public static final String TENANT_PACKAGE_MENU_IDS_BY_PRODUCT = "tenant_package_menu_ids_by_product#12h";
/**
* 系统配置
@@ -131,4 +130,4 @@ public class RedisKeyConstants {
* 自定义板编号
*/
public static final String CUSTOM_PLATE_NO = "custom_plateno";
}
}
@@ -74,14 +74,6 @@ public interface TenantPackageService {
*/
List<TenantPackageDO> getTenantPackageListByStatus(Integer status);
/**
* 获取组织套餐下的权限菜单id
*
* @param id 组织套餐id
* @return
*/
Set<Long> getTenantPackageMenuIds(Long id);
/**
* 获取产品套餐下的权限菜单id
*
@@ -18,10 +18,13 @@ import com.cf.imes.module.system.dal.mysql.organ.TenantPackageMapper;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.cf.imes.module.system.dal.redis.RedisKeyConstants;
import com.cf.imes.module.system.service.permission.PermissionService;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.validation.annotation.Validated;
import jakarta.annotation.Resource;
@@ -50,6 +53,9 @@ public class TenantPackageServiceImpl implements TenantPackageService {
@Resource
private PermissionService permissionService;
@Resource(name = "redisCacheManager")
private CacheManager redisCacheManager;
@Override
public Long createTenantPackage(TenantPackageSaveReqVO createReqVO) {
// 唯一性校验
@@ -63,7 +69,6 @@ public class TenantPackageServiceImpl implements TenantPackageService {
@Override
@DSTransactional // 多数据源,使用 @DSTransactional 保证本地事务,以及数据源的切换
@CacheEvict(value = RedisKeyConstants.TENANT_PACKAGE_MENU_IDS, key = "#updateReqVO.id")
public void updateTenantPackage(TenantPackageSaveReqVO updateReqVO) {
// 唯一性校验
validateTenantPackageUnique(updateReqVO);
@@ -82,13 +87,13 @@ public class TenantPackageServiceImpl implements TenantPackageService {
List<OrganizationDO> tenants = organService.getOrganListByPackageId(tenantPackage.getId());
permissionService.flushCacheWhenTenantPackageChange(CollectionUtils.convertList(tenants, OrganizationDO::getId));
}
evictProductMenuCacheAfterCommit(tenantPackage.getProductId());
}
@Override
@CacheEvict(value = RedisKeyConstants.TENANT_PACKAGE_MENU_IDS, key = "#id")
public void deleteTenantPackage(Long id) {
// 校验存在
validateTenantPackageExists(id);
TenantPackageDO tenantPackage = validateTenantPackageExists(id);
if(Objects.equals(id, SYSTEM_ORGAN_PACKAGE_ID) || Objects.equals(id, SYSTEM_SUPER_PACKAGE_ID)) {
throw new ServiceException(TENANT_PACKAGE_DELETED_EXIT);
}
@@ -97,6 +102,7 @@ public class TenantPackageServiceImpl implements TenantPackageService {
validateOrganUsed(id);
// 删除
tenantPackageMapper.deleteById(id);
evictProductMenuCacheAfterCommit(tenantPackage.getProductId());
}
private TenantPackageDO validateTenantPackageExists(Long id) {
@@ -156,19 +162,7 @@ public class TenantPackageServiceImpl implements TenantPackageService {
}
@Override
@Cacheable(value = RedisKeyConstants.TENANT_PACKAGE_MENU_IDS, key = "#id", unless = "#result == null", cacheManager = "redisCacheManager")
public Set<Long> getTenantPackageMenuIds(Long id) {
validateTenantPackageExists(id);
TenantPackageDO tenantPackageDO = tenantPackageMapper.selectOne(new LambdaQueryWrapper<TenantPackageDO>().eq(TenantPackageDO::getId, id).select(TenantPackageDO::getMenuIds));
if (ObjectUtil.isNotNull(tenantPackageDO)) {
return tenantPackageDO.getMenuIds();
} else {
return null;
}
}
@Override
@Cacheable(value = RedisKeyConstants.TENANT_PACKAGE_MENU_IDS, key = "#productId", unless = "#result == null or #result.isEmpty()", cacheManager = "redisCacheManager")
@Cacheable(value = RedisKeyConstants.TENANT_PACKAGE_MENU_IDS_BY_PRODUCT, key = "#productId", unless = "#result == null or #result.isEmpty()", cacheManager = "redisCacheManager")
public Set<Long> getProductTenantPackageMenuIds(Long productId) {
TenantPackageDO tenantPackageDO = tenantPackageMapper.selectOne(new LambdaQueryWrapper<TenantPackageDO>().eq(TenantPackageDO::getProductId, productId).select(TenantPackageDO::getMenuIds));
if (ObjectUtil.isNotNull(tenantPackageDO)) {
@@ -177,4 +171,31 @@ public class TenantPackageServiceImpl implements TenantPackageService {
return Set.of();
}
}
/**
* 套餐菜单发生变化后,事务提交成功再清理产品菜单缓存。
*
* @param productId 产品编号
*/
private void evictProductMenuCacheAfterCommit(Long productId) {
if (productId == null) {
return;
}
Runnable evict = () -> {
Cache cache = redisCacheManager.getCache(RedisKeyConstants.TENANT_PACKAGE_MENU_IDS_BY_PRODUCT);
if (cache != null) {
cache.evict(productId);
}
};
if (TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
evict.run();
}
});
} else {
evict.run();
}
}
}