Explorar o código

小程序配置获取优化,总后台联动小程序配置

yjwang hai 1 semana
pai
achega
1b59222efc

+ 33 - 0
fs-admin/src/main/java/com/fs/course/controller/FsCoursePlaySourceConfigController.java

@@ -18,6 +18,8 @@ import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.utils.ServletUtils;
 import com.fs.common.utils.bean.BeanUtils;
+import com.fs.common.utils.spring.SpringUtils;
+import com.fs.common.core.redis.RedisCache;
 import com.fs.course.config.CourseConfig;
 import com.fs.course.domain.FsCoursePlaySourceConfig;
 import com.fs.course.enums.MiniProgramAgreementEnum;
@@ -34,17 +36,20 @@ import com.fs.his.service.MiniProgramAgreementService;
 import com.fs.system.service.ISysConfigService;
 import com.github.pagehelper.PageHelper;
 import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
 import java.time.LocalDateTime;
 import java.util.*;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 @RestController
 @RequestMapping("/course/playSourceConfig")
 @AllArgsConstructor
+@Slf4j
 public class FsCoursePlaySourceConfigController extends BaseController {
 
     private final IFsCoursePlaySourceConfigService fsCoursePlaySourceConfigService;
@@ -135,6 +140,10 @@ public class FsCoursePlaySourceConfigController extends BaseController {
         config.setCreateTime(LocalDateTime.now());
         config.setUpdateTime(LocalDateTime.now());
         fsCoursePlaySourceConfigService.save(config);
+
+        // 新增配置后直接更新 Redis 缓存
+        refreshRedisCache(config);
+
         return AjaxResult.success();
     }
 
@@ -169,6 +178,10 @@ public class FsCoursePlaySourceConfigController extends BaseController {
         applyCompanyIds(param.getCompanyId(), param.getCompanyIds(), config);
 
         fsCoursePlaySourceConfigService.updateById(config);
+
+        // 修改配置后直接更新 Redis 缓存
+        refreshRedisCache(config);
+
         return AjaxResult.success();
     }
 
@@ -348,6 +361,26 @@ public class FsCoursePlaySourceConfigController extends BaseController {
         return AjaxResult.success(result);
     }
 
+    /**
+     * 小程序配置 Redis 缓存 key 前缀(与 WxMaConfiguration 保持一致)
+     */
+    private static final String MINIPROGRAM_CONFIG_CACHE_KEY = "miniprogram:config:";
+
+    /**
+     * 更新 Redis 中的小程序配置缓存,随机 6-8 小时过期
+     */
+    private static void refreshRedisCache(FsCoursePlaySourceConfig config) {
+        try {
+            RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
+            String redisKey = MINIPROGRAM_CONFIG_CACHE_KEY + config.getAppid();
+            int hours = new Random().nextInt(3) + 6;
+            redisCache.setCacheObject(redisKey, config, hours, TimeUnit.HOURS);
+        } catch (Exception e) {
+            // Redis 异常不影响主流程,缓存会在下次读取时自动回源 DB
+            log.warn("更新小程序配置Redis缓存失败,appId: {}", config.getAppid(), e);
+        }
+    }
+
     private static void applyCompanyIds(Long companyId, List<Long> companyIds, FsCoursePlaySourceConfig config) {
         List<Long> ids = new ArrayList<>();
         if (companyIds != null) {

+ 33 - 5
fs-service/src/main/java/com/fs/core/config/WxMaConfiguration.java

@@ -12,6 +12,7 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.common.utils.spring.SpringUtils;
+import com.fs.common.core.redis.RedisCache;
 import com.fs.course.config.CourseMaConfig;
 import com.fs.course.domain.FsCoursePlaySourceConfig;
 import com.fs.course.mapper.FsCoursePlaySourceConfigMapper;
@@ -38,7 +39,10 @@ import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
+import java.util.Random;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 @Slf4j
@@ -106,20 +110,44 @@ public class WxMaConfiguration {
         log.info("配置加载完毕! 配置文件: {}",JSON.toJSONString(this.properties));
     }
 
+    /**
+     * 小程序配置 Redis 缓存 key 前缀
+     */
+    private static final String MINIPROGRAM_CONFIG_CACHE_KEY = "miniprogram:config:";
+
     public static WxMaService getMaService(String appid) {
-        return maServices.computeIfAbsent(appid,e->{
-            // 查询数据库
+        RedisCache redisCache = SpringUtils.getBean(RedisCache.class);
+        String redisKey = MINIPROGRAM_CONFIG_CACHE_KEY + appid;
+
+        FsCoursePlaySourceConfig config = redisCache.getCacheObject(redisKey);
+
+        if (config == null) {
             FsCoursePlaySourceConfigMapper configMapper = SpringUtils.getBean(FsCoursePlaySourceConfigMapper.class);
             Wrapper<FsCoursePlaySourceConfig> queryWrapper = Wrappers.<FsCoursePlaySourceConfig>lambdaQuery()
                     .eq(FsCoursePlaySourceConfig::getAppid, appid)
                     .eq(FsCoursePlaySourceConfig::getIsDel, 0);
-            FsCoursePlaySourceConfig config = configMapper.selectOne(queryWrapper);
+            config = configMapper.selectOne(queryWrapper);
             if (config == null) {
                 throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid));
             }
 
-            return getWxMaService(config.getAppid(), config.getSecret(), config.getToken(), config.getAesKey(), config.getMsgDataFormat());
-        });
+            int hours = new Random().nextInt(3) + 6;
+            redisCache.setCacheObject(redisKey, config, hours, TimeUnit.HOURS);
+            log.info("小程序配置缓存未命中,从DB加载并缓存至Redis,appId: {}, 过期时间: {}小时", appid, hours);
+        }
+
+        return getWxMaService(config.getAppid(), config.getSecret(), config.getToken(), config.getAesKey(), config.getMsgDataFormat());
+    }
+
+    /**
+     * 刷新指定 appId 的小程序配置缓存
+     * 场景:线上修改了 fs_course_play_source_config 表的 secret 后,调用此方法清除缓存,
+     * 下次 getMaService 会重新从 DB 加载最新配置,无需重启应用
+     */
+    public static void refreshMaService(String appid) {
+        maServices.remove(appid);
+        routers.remove(appid);
+        log.info("已清除小程序配置缓存,appId: {}", appid);
     }
 
     /**