Browse Source

feat: common缓存

wangcheng 2 năm trước cách đây
mục cha
commit
2fa55cd51b

+ 32 - 87
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/PlanNewCommonOutController.java

@@ -7,6 +7,7 @@ import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONArray;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
 import com.plumelog.core.util.LogExceptionStackTrace;
 import com.webflux.launchadmin.global.BaseException;
 import com.webflux.launchadmin.mysql.controller.planNew.req.KefuRequest;
@@ -26,6 +27,7 @@ import com.webflux.launchadmin.mysql.service.planNew.structure.Item;
 import com.webflux.launchadmin.mysql.service.takeaway.TakeawayServicesInterface;
 import com.webflux.launchcommon.returnObj.RStatus;
 import com.webflux.launchcommon.utils.StringUtils;
+import com.weblux.launchredis.utils.RedisKey;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.data.domain.Sort;
@@ -83,70 +85,16 @@ public class PlanNewCommonOutController {
      * @return {@link Mono}<{@link RStatus}<{@link PlanNewCommon}>>
      */
     @GetMapping("getPlanNewCommonH5")
-    public Mono<RStatus<byte[]>> getPlanNewCommonH5(@RequestParam("code") String code) {
-        Mono<PlanNewCommon> planNewCommonMono = template.selectOne(Query.query(Criteria.where("code").is(code)), PlanNewCommon.class)
-                .switchIfEmpty(Mono.error(new BaseException("计划code异")))
-                .onErrorResume(throwable -> Mono.error(new BaseException("计划code异")));
-        Mono<PlanNewCommonRes> resMono = planNewCommonMono.flatMap(f -> {
-            // 群成员
-            Mono<List<GroupUserRes>> groupUserResMono = Mono.just(new ArrayList<>());
-            // 群封面
-            Mono<List<Image>> imageMono = template.select(Query.query(Criteria.where("type").is(1)
-                            .and("group_type_id").is(f.groupId())
-                            .and("deleted_at").isNull()), Image.class)
-                    .onErrorResume(throwable -> Mono.error(new BaseException("获取群封面异常"))).collectList();
-            // 群名称
-            Mono<List<Material>> textMono = template.select(Query.query(Criteria.where("type").is(4)
-                            .and("deleted_at").isNull()
-                            .and("group_type_id").is(f.groupId())), Material.class)
-                    .onErrorResume(throwable -> Mono.error(new BaseException("获取群名称异常"))).collectList();
-            if (3 == f.type()) {
-                // 交友裂变, 需要群成员
-                Mono<List<GroupUsers>> groupUsersMono = template.select(Query.query(Criteria.where("group_users_type").is(f.groupId())).limit(14), GroupUsers.class)
-                        .onErrorResume(throwable -> Mono.error(new BaseException("获取群成员异常"))).collectList();
-                groupUserResMono = groupUsersMono.flatMap(groupUsers -> {
-                    List<GroupUserRes> groupUserResList = groupUsers.stream().map(groupUsers1 -> {
-                        GroupUserRes groupUserRes = new GroupUserRes();
-                        groupUserRes.setUserHead(groupUsers1.groupUsersHead());
-                        groupUserRes.setUserNickname(groupUsers1.groupUsersNickname());
-                        return groupUserRes;
-                    }).collect(Collectors.toList());
-                    return Mono.just(groupUserResList);
-                });
-            }
-            return Mono.zip(Mono.just(f), groupUserResMono, imageMono, textMono).flatMap(tuple -> {
-                PlanNewCommon plan = tuple.getT1();
-                PlanNewCommonRes res = new PlanNewCommonRes();
-                res.setCode(plan.code());
-                res.setType(plan.type());
-                res.setName(plan.name());
-                res.setGroupId(plan.groupId());
-                res.setPosterTemplateId(plan.posterTemplateId());
-                res.setImportDomain(plan.importDomain());
-                res.setConfigJson(plan.configJson());
-                res.setGroupUserList(tuple.getT2());
-                List<H5ImageAndText> h5ImageAndTextList = new ArrayList<>();
-                H5ImageAndText h5ImageAndText = new H5ImageAndText();
-                List<Image> imageList = tuple.getT3();
-                if (!imageList.isEmpty()) {
-                    Image image = imageList.get(RandomUtil.randomInt(0, imageList.size()));
-                    h5ImageAndText.setImage(image.image());
-                }
-
-                List<Material> materialList = tuple.getT4();
-                if (!materialList.isEmpty()) {
-                    Material material = materialList.get(RandomUtil.randomInt(0, materialList.size()));
-                    h5ImageAndText.setName(material.content());
-                    h5ImageAndText.setRemark(material.remark());
-                }
-                h5ImageAndTextList.add(h5ImageAndText);
-                res.setGroupImageAndTextList(h5ImageAndTextList);
-                return Mono.just(res);
-            });
-        });
-        // GZIP压缩
-        Mono<byte[]> res = resMono.flatMap(f -> Mono.just(Objects.requireNonNull(this.compressData(JSONUtil.toJsonStr(f)))));
-        return RStatus.success(res);
+    public Mono<RStatus<PlanNewCommonRes>> getPlanNewCommonH5(@RequestParam("code") String code) {
+        Mono<PlanNewCommonRes> resMono;
+        Object obj = stringRedisTemplate.opsForHash().get(RedisKey.PLAN_COMMON_INFO_H5, code);
+        if (obj != null) {
+            PlanNewCommonRes res = JSON.parseObject(obj.toString(), PlanNewCommonRes.class);
+            resMono = Mono.just(res);
+        } else {
+            resMono = planServiceInterface.getPlanNewCommonH5(code);
+        }
+        return RStatus.success(resMono);
     }
 
     /**
@@ -175,7 +123,7 @@ public class PlanNewCommonOutController {
     public Mono<RStatus<byte[]>> kefuList(@RequestBody KefuRequest request) {
         Mono<PlanNewCommon> code = template.selectOne(Query.query(Criteria.where("code").is(request.getCode())), PlanNewCommon.class)
                 .switchIfEmpty(Mono.error(new BaseException("code查询返回结构为空")))
-                .onErrorResume(throwable -> Mono.error(new BaseException("code查询返回结为空")));
+                .onErrorResume(throwable -> Mono.error(new BaseException("code查询返回结为空")));
         Mono<DataListsKefu> dataListsKefuMono = code.flatMap(planNew -> {
             Mono<List<Image>> image = template.select(Query.query(Criteria.where("type").is(5)
                             .and("deleted_at").isNull()
@@ -294,7 +242,7 @@ public class PlanNewCommonOutController {
                                 .and("type").is(5)
                                 .and("deleted_at").isNull()), DomainSelect.class)
                         .switchIfEmpty(Mono.error(new BaseException("transferPageDomain 域名查詢為空 group_type_id:::" + f.transferPageDomain())))
-                        .onErrorResume(throwable -> Mono.error(new BaseException("transferPageDomain 域名查詢為空 group_type_id:::" + f.transferPageDomain()))).collectList().flatMap(fff -> {
+                        .onErrorResume(throwable -> Mono.error(new BaseException(throwable.getMessage()))).collectList().flatMap(fff -> {
                             if (!fff.isEmpty()) {
                                 DomainSelect domainSelect = fff.get(RandomUtil.randomInt(0, fff.size()));
                                 String string = RandomUtil.randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6);
@@ -316,7 +264,7 @@ public class PlanNewCommonOutController {
                                 .and("type").is(4)
                                 .and("deleted_at").isNull()), DomainSelect.class)
                         .switchIfEmpty(Mono.error(new BaseException("backgroupDomain 域名查询为空 group_type_id" + f.backgroupDomain())))
-                        .onErrorResume(throwable -> Mono.error(new BaseException("backgroupDomain 域名查询为空 group_type_id" + f.backgroupDomain()))).collectList().flatMap(fff -> {
+                        .onErrorResume(throwable -> Mono.error(new BaseException(throwable.getMessage()))).collectList().flatMap(fff -> {
                             if (!fff.isEmpty()) {
                                 DomainSelect domainSelect = fff.get(RandomUtil.randomInt(0, fff.size()));
                                 String string = RandomUtil.randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6);
@@ -335,7 +283,7 @@ public class PlanNewCommonOutController {
                             .and("type").is(request.getType())
                             .and("deleted_at").isNull()), DomainSelect.class)
                     .switchIfEmpty(Mono.error(new BaseException("查询domain 返回结果为空")))
-                    .onErrorResume(throwable -> Mono.error(new BaseException("查询domain 返回结果为空"))).collectList().flatMap(fm -> {
+                    .onErrorResume(throwable -> Mono.error(new BaseException(throwable.getMessage()))).collectList().flatMap(fm -> {
                         //  DomainSelectRes domainSelectRes = new DomainSelectRes();
                         int i = RandomUtil.randomInt(0, fm.size());
                         String domain = fm.get(i).domain();
@@ -369,7 +317,7 @@ public class PlanNewCommonOutController {
                         .and("type").is(request.getType())
                         .and("deleted_at").isNull()), DomainSelect.class)
                 .switchIfEmpty(Mono.error(new BaseException("查询domain 返回结果为空")))
-                .onErrorResume(throwable -> Mono.error(new BaseException("查询domain 返回结果为空"))).collectList()
+                .onErrorResume(throwable -> Mono.error(new BaseException(throwable.getMessage()))).collectList()
                 .flatMap(fm -> {
                     DomainSelectRes domainSelectRes = new DomainSelectRes();
                     int i = RandomUtil.randomInt(0, fm.size());
@@ -397,7 +345,7 @@ public class PlanNewCommonOutController {
                             .and("deleted_at").isNull()
                             .and("type").is(request.getType())), DomainSelect.class)
                     .switchIfEmpty(Mono.error(new BaseException("查询domain 返回结果为空")))
-                    .onErrorResume(throwable -> Mono.error(new BaseException("查询domain 返回结果为空")))
+                    .onErrorResume(throwable -> Mono.error(new BaseException(throwable.getMessage())))
                     .collectList().flatMap(fm -> {
                         int i = RandomUtil.randomInt(0, fm.size());
                         String domain = fm.get(i).domain();
@@ -556,24 +504,21 @@ public class PlanNewCommonOutController {
         if (Objects.isNull(id) || id <= 0) {
             return Mono.just(getAudio());
         }
-        return template.selectOne(Query.query(Criteria.where("id").is(id)), Audio.class)
-                .switchIfEmpty(Mono.error(new BaseException(StrUtil.format("通过计划retAudioId:{}查询音频为空", id))))
-                .onErrorResume(throwable -> Mono.error(new BaseException(StrUtil.format("通过计划retAudioId:{}查询音频Error::{}", id, throwable.getMessage()))));
-        // String value = redisTemplate.opsForValue().get(RedisKey.FISSION_AUDIO + id);
+        String value = stringRedisTemplate.opsForValue().get(RedisKey.FISSION_AUDIO + id);
+        if (null == value || StrUtil.isBlank(value)) {
+            value = " ";
+        }
         // 优先读缓存
-        // Mono<String> obj = reactiveRedisTemplate.opsForValue().get(RedisKey.FISSION_AUDIO + id)
-        //         .switchIfEmpty(Mono.just(" "))
-        //         .onErrorResume(throwable -> Mono.error(new BaseException(StrUtil.format("通过计划retAudioId:{}查询音频Error::", id, throwable.getMessage()))));
-        // return obj.flatMap(val -> {
-        //     if (val != null && StrUtil.isNotBlank(val.toString())) {
-        //         Audio audio = JSON.parseObject(val.toString(), Audio.class);
-        //         return Mono.just(audio);
-        //     } else {
-        //         return template.selectOne(Query.query(Criteria.where("id").is(id)), Audio.class)
-        //                 .switchIfEmpty(Mono.error(new BaseException(StrUtil.format("通过计划retAudioId:{}查询音频为空", id))))
-        //                 .onErrorResume(throwable -> Mono.error(new BaseException(StrUtil.format("通过计划retAudioId:{}查询音频Error::", id, throwable.getMessage()))));
-        //     }
-        // });
+        return Mono.just(value).flatMap(val -> {
+            if (val != null && StrUtil.isNotBlank(val)) {
+                Audio audio = JSON.parseObject(val, Audio.class);
+                return Mono.just(audio);
+            } else {
+                return template.selectOne(Query.query(Criteria.where("id").is(id)), Audio.class)
+                        .switchIfEmpty(Mono.error(new BaseException(StrUtil.format("通过计划retAudioId:{}查询音频为空", id))))
+                        .onErrorResume(throwable -> Mono.error(new BaseException(StrUtil.format("通过计划retAudioId:{}查询音频Error::{}", id, throwable.getMessage()))));
+            }
+        });
     }
 
     private Audio getAudio() {

+ 39 - 14
launch-admin/src/main/java/com/webflux/launchadmin/mysql/service/groupUsers/GroupUsersServiceImpl.java

@@ -1,5 +1,6 @@
 package com.webflux.launchadmin.mysql.service.groupUsers;
 
+import com.alibaba.fastjson.JSON;
 import com.webflux.launchadmin.config.BaseContextHandler;
 import com.webflux.launchadmin.global.BaseException;
 import com.webflux.launchadmin.mysql.controller.groupUsers.res.DeleteRes;
@@ -11,10 +12,12 @@ import com.webflux.launchadmin.mysql.entity.planNew.PlanNew;
 import com.webflux.launchadmin.mysql.repository.groupUsers.GroupUsersRepository;
 import com.webflux.launchcommon.returnObj.Paged;
 import com.webflux.launchcommon.returnObj.RStatus;
+import com.weblux.launchredis.utils.RedisKey;
 import jakarta.annotation.Resource;
 import org.springframework.data.domain.*;
 import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
 import org.springframework.data.r2dbc.repository.R2dbcRepository;
+import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.data.relational.core.query.Criteria;
 import org.springframework.data.relational.core.query.Query;
 import org.springframework.stereotype.Service;
@@ -33,27 +36,29 @@ public class GroupUsersServiceImpl implements GroupUsersServiceInterface {
     private GroupUsersRepository groupUsersRepository;
     @Resource
     private R2dbcEntityTemplate template;
+    @Resource
+    private StringRedisTemplate stringRedisTemplate;
 
     @Override
     public Mono<RStatus<Paged<GroupUsersRes>>> page(Integer type, int page, int size) {
         Criteria criteria = Criteria.empty();
-        if (Objects.nonNull(type) &&type>0) {
+        if (Objects.nonNull(type) && type > 0) {
             criteria = criteria.and("group_users_type").is(type);
         }
         Query query = Query.query(criteria);
-        int skip = (page - 1) *size;
+        int skip = (page - 1) * size;
         int limit = size;
         Mono<Long> count = template.count(query, GroupUsers.class);
         Mono<List<GroupUsers>> created_at = template.select(Query.query(criteria)
-                .offset(skip)
-                .limit(limit)
-                .sort(Sort.by(Sort.Order.desc("created_at"))), GroupUsers.class)
+                        .offset(skip)
+                        .limit(limit)
+                        .sort(Sort.by(Sort.Order.desc("created_at"))), GroupUsers.class)
                 .onErrorResume(throwable -> Mono.error(new BaseException("查询失败::error::" + throwable.getMessage())))
                 .collectList();
         Mono<Paged<GroupUsersRes>> id1 = Mono.zip(count, created_at).flatMap(f -> {
             List<GroupUsers> t2 = f.getT2();
             List<Integer> collect = t2.stream()
-                    .filter(f3->Objects.nonNull(f3.groupUsersType()))
+                    .filter(f3 -> Objects.nonNull(f3.groupUsersType()))
                     .map(GroupUsers::groupUsersType)
                     .collect(Collectors.toList());
             if (collect.isEmpty()) {
@@ -92,20 +97,29 @@ public class GroupUsersServiceImpl implements GroupUsersServiceInterface {
 
     @Override
     public Mono<RStatus<DeleteRes>> deletePosterById(Long[] groupUsersId) {
+        Flux<GroupUsers> groupUsersFlux = groupUsersRepository.findAllById(List.of(groupUsersId));
         Mono<DeleteRes> deleteResMono = groupUsersRepository
                 .deleteAllById(List.of(groupUsersId))
                 .then(Mono.just(new DeleteRes(List.of(groupUsersId))))
-                .onErrorResume(throwable -> Mono.error(new BaseException("删除::error::" + throwable.getMessage())));
+                .onErrorResume(throwable -> Mono.error(new BaseException("删除::error::" + throwable.getMessage())))
+                .flatMap(f -> {
+                    groupUsersFlux.flatMap(g -> {
+                        stringRedisTemplate.opsForSet().remove(RedisKey.GROUP_USERS_TYPE + g.groupUsersType(), g.groupUsersId().toString());
+                        stringRedisTemplate.delete(RedisKey.GROUP_USERS + g.groupUsersId());
+                        return Mono.just(g);
+                    });
+                    return Mono.just(f);
+                });
         return RStatus.success(deleteResMono);
     }
 
     @Override
     public Mono<RStatus<GroupUsers>> saveOrUpdate(GroupUsersDto groupUsersDto) {
         ZonedDateTime now = ZonedDateTime.now();
-        if(Objects.isNull(groupUsersDto.getGroupUsersId())){
+        if (Objects.isNull(groupUsersDto.getGroupUsersId())) {
             Mono<GroupUsers> insert = insertGroupUsersMono(groupUsersDto, BaseContextHandler.getUserName(), BaseContextHandler.getUserId(), now);
             return RStatus.success(insert);
-        }else {
+        } else {
             Mono<GroupUsers> groupUsersMono = updateGroupUsersMono(groupUsersDto, now);
             return RStatus.success(groupUsersMono);
         }
@@ -115,7 +129,7 @@ public class GroupUsersServiceImpl implements GroupUsersServiceInterface {
     public Mono<RStatus<GroupUsers>> getById(Long groupUsersId) {
         Mono<GroupUsers> groupUsersMono = groupUsersRepository
                 .findById(groupUsersId)
-                .switchIfEmpty( Mono.error(new BaseException("id异常 查询结果为空")))
+                .switchIfEmpty(Mono.error(new BaseException("id异常 查询结果为空")))
                 .onErrorResume(throwable -> Mono.error(new BaseException("查询失败::" + throwable.getMessage())));
         return RStatus.success(groupUsersMono);
     }
@@ -133,8 +147,14 @@ public class GroupUsersServiceImpl implements GroupUsersServiceInterface {
                             f.createUser(),
                             f.createId()
                     );
-                 return groupUsersRepository.save(groupUsers)
-                         .onErrorResume(throwable -> Mono.error(new BaseException("修改失败::" + throwable.getMessage())));
+                    return groupUsersRepository.save(groupUsers)
+                            .onErrorResume(throwable -> Mono.error(new BaseException("修改失败::" + throwable.getMessage())))
+                            .flatMap(g -> {
+                                stringRedisTemplate.opsForSet().remove(RedisKey.GROUP_USERS_TYPE + f.groupUsersType(), f.groupUsersId().toString());
+                                stringRedisTemplate.opsForSet().add(RedisKey.GROUP_USERS_TYPE + g.groupUsersType(), g.groupUsersId().toString());
+                                stringRedisTemplate.opsForValue().set(RedisKey.GROUP_USERS + g.groupUsersId(), JSON.toJSONString(g));
+                                return Mono.just(g);
+                            });
                 });
     }
 
@@ -143,13 +163,18 @@ public class GroupUsersServiceImpl implements GroupUsersServiceInterface {
                 groupUsersDto.getGroupUsersHead(),
                 groupUsersDto.getGroupUsersNickname(),
                 now,
-               null,
+                null,
                 groupUsersDto.getGroupUsersType(),
                 userName,
                 userId
         );
         return template.insert(groupUsers)
-                .onErrorResume(throwable -> Mono.error(new BaseException("插入失败::"+ throwable.getMessage())));
+                .onErrorResume(throwable -> Mono.error(new BaseException("插入失败::" + throwable.getMessage())))
+                .flatMap(f -> {
+                    stringRedisTemplate.opsForSet().add(RedisKey.GROUP_USERS_TYPE + f.groupUsersType(), f.groupUsersId().toString());
+                    stringRedisTemplate.opsForValue().set(RedisKey.GROUP_USERS + f.groupUsersId(), JSON.toJSONString(f));
+                    return Mono.just(f);
+                });
     }
 }
 

+ 112 - 6
launch-admin/src/main/java/com/webflux/launchadmin/mysql/service/planNew/PlanServiceImpl.java

@@ -1,17 +1,24 @@
 package com.webflux.launchadmin.mysql.service.planNew;
 
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
+import com.webflux.launchadmin.global.BaseException;
 import com.webflux.launchadmin.mysql.controller.listening.res.ListeningPlanNewRes;
 import com.webflux.launchadmin.mysql.controller.listening.res.ListeningPlanNewRes2;
 import com.webflux.launchadmin.mysql.controller.planNew.req.PlanReqPage;
-import com.webflux.launchadmin.mysql.entity.planNew.GroupType;
-import com.webflux.launchadmin.mysql.entity.planNew.PlanNew;
-import com.webflux.launchadmin.mysql.entity.planNew.PlanNewCommon;
-import com.webflux.launchadmin.mysql.entity.planNew.PosterTemplate;
+import com.webflux.launchadmin.mysql.controller.planNew.res.GroupUserRes;
+import com.webflux.launchadmin.mysql.controller.planNew.res.H5ImageAndText;
+import com.webflux.launchadmin.mysql.controller.planNew.res.PlanNewCommonRes;
+import com.webflux.launchadmin.mysql.entity.groupUsers.GroupUsers;
+import com.webflux.launchadmin.mysql.entity.planNew.*;
 import com.webflux.launchcommon.returnObj.Paged;
 import com.webflux.launchcommon.returnObj.RStatus;
+import com.webflux.launchcommon.utils.StringUtils;
 import com.weblux.launchredis.utils.RedisKey;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
@@ -26,8 +33,7 @@ import java.time.Duration;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
-import java.util.Comparator;
-import java.util.List;
+import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
@@ -112,4 +118,104 @@ public class PlanServiceImpl implements PlanServiceInterface {
         }
         return integer;
     }
+
+    @Override
+    public Mono<PlanNewCommonRes> getPlanNewCommonH5(String code) {
+        Mono<PlanNewCommon> planNewCommonMono = template.selectOne(Query.query(Criteria.where("code").is(code)), PlanNewCommon.class)
+                .switchIfEmpty(Mono.error(new BaseException("计划code异常:" + ExceptionUtils.getStackTrace(new Exception()))))
+                .onErrorResume(throwable -> Mono.error(new BaseException(throwable.getMessage())));
+        Mono<PlanNewCommonRes> resMono = planNewCommonMono.flatMap(f -> {
+            // 群成员
+            Mono<List<GroupUserRes>> groupUserResMono = Mono.just(new ArrayList<>());
+            // 群封面
+            Mono<List<Image>> imageMono = template.select(Query.query(Criteria.where("type").is(1)
+                            .and("group_type_id").is(f.groupId())
+                            .and("deleted_at").isNull()), Image.class)
+                    .onErrorResume(throwable -> Mono.error(new BaseException(throwable.getMessage()))).collectList();
+            // 群名称
+            Mono<List<Material>> textMono = template.select(Query.query(Criteria.where("type").is(4)
+                            .and("deleted_at").isNull()
+                            .and("group_type_id").is(f.groupId())), Material.class)
+                    .onErrorResume(throwable -> Mono.error(new BaseException(throwable.getMessage()))).collectList();
+            if (3 == f.type()) {
+                // 交友裂变, 需要群成员
+                groupUserResMono = this.getGroupUsers(f.groupId());
+            }
+            return Mono.zip(Mono.just(f), groupUserResMono, imageMono, textMono).flatMap(tuple -> {
+                PlanNewCommon plan = tuple.getT1();
+                PlanNewCommonRes res = new PlanNewCommonRes();
+                res.setCode(plan.code());
+                res.setType(plan.type());
+                res.setName(plan.name());
+                res.setGroupId(plan.groupId());
+                res.setPosterTemplateId(plan.posterTemplateId());
+                res.setImportDomain(plan.importDomain());
+                res.setConfigJson(plan.configJson());
+                res.setGroupUserList(tuple.getT2());
+                List<H5ImageAndText> h5ImageAndTextList = new ArrayList<>();
+                H5ImageAndText h5ImageAndText = new H5ImageAndText();
+                List<Image> imageList = tuple.getT3();
+                if (!imageList.isEmpty()) {
+                    Image image = imageList.get(RandomUtil.randomInt(0, imageList.size()));
+                    h5ImageAndText.setImage(image.image());
+                }
+
+                List<Material> materialList = tuple.getT4();
+                if (!materialList.isEmpty()) {
+                    Material material = materialList.get(RandomUtil.randomInt(0, materialList.size()));
+                    h5ImageAndText.setName(material.content());
+                    h5ImageAndText.setRemark(material.remark());
+                }
+                h5ImageAndTextList.add(h5ImageAndText);
+                res.setGroupImageAndTextList(h5ImageAndTextList);
+                return Mono.just(res);
+            });
+        });
+        return resMono;
+    }
+
+    /** 获取群成员,优先从缓存中获取 */
+    private Mono<List<GroupUserRes>> getGroupUsers(Long groupId) {
+        if (null == groupId || groupId <= 0) {
+            return Mono.just(new ArrayList<>());
+        }
+        Mono<List<GroupUsers>> groupUsersMono;
+        String typeKey = RedisKey.GROUP_USERS_TYPE + groupId;
+        if (Boolean.FALSE.equals(stringRedisTemplate.hasKey(typeKey))) {
+            groupUsersMono = this.getGroupUsersByDb(groupId);
+        } else {
+            Set<String> groupUserIdSet = stringRedisTemplate.opsForSet().members(RedisKey.GROUP_USERS_TYPE + groupId);
+            if (null == groupUserIdSet || groupUserIdSet.isEmpty()) {
+                groupUsersMono = this.getGroupUsersByDb(groupId);
+            } else {
+                if (groupUserIdSet.size() > 14) {
+                    groupUserIdSet = groupUserIdSet.stream().limit(14).collect(Collectors.toSet());
+                }
+                List<GroupUsers> groupUsers = new ArrayList<>();
+                for (String groupUserId : groupUserIdSet) {
+                    String val = stringRedisTemplate.opsForValue().get(RedisKey.GROUP_USERS + groupUserId);
+                    if (null == val || val.isEmpty()) {
+                        continue;
+                    }
+                    groupUsers.add(JSON.parseObject(val, GroupUsers.class));
+                }
+                groupUsersMono = Mono.just(groupUsers);
+            }
+        }
+        return groupUsersMono.flatMap(groupUsers -> {
+            List<GroupUserRes> groupUserResList = groupUsers.stream().map(groupUsers1 -> {
+                GroupUserRes groupUserRes = new GroupUserRes();
+                groupUserRes.setUserHead(groupUsers1.groupUsersHead());
+                groupUserRes.setUserNickname(groupUsers1.groupUsersNickname());
+                return groupUserRes;
+            }).collect(Collectors.toList());
+            return Mono.just(groupUserResList);
+        });
+    }
+
+    private Mono<List<GroupUsers>> getGroupUsersByDb(Long groupId) {
+        return template.select(Query.query(Criteria.where("group_users_type").is(groupId)).limit(14), GroupUsers.class)
+                .onErrorResume(throwable -> Mono.error(new BaseException(throwable.getMessage() + "4"))).collectList();
+    }
+
 }

+ 4 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/service/planNew/PlanServiceInterface.java

@@ -2,9 +2,11 @@ package com.webflux.launchadmin.mysql.service.planNew;
 
 import com.webflux.launchadmin.mysql.controller.listening.res.ListeningPlanNewRes2;
 import com.webflux.launchadmin.mysql.controller.planNew.req.PlanReqPage;
+import com.webflux.launchadmin.mysql.controller.planNew.res.PlanNewCommonRes;
 import com.webflux.launchcommon.returnObj.Paged;
 import com.webflux.launchcommon.returnObj.RStatus;
 import org.springframework.data.relational.core.query.Criteria;
+import org.springframework.web.bind.annotation.RequestParam;
 import reactor.core.publisher.Mono;
 
 /**
@@ -14,4 +16,6 @@ public interface PlanServiceInterface {
     Mono<RStatus<Paged<ListeningPlanNewRes2>>> page(PlanReqPage request, Criteria criteria);
 
     Integer setUserVisitsToRedis(String unique, String code);
+
+    Mono<PlanNewCommonRes> getPlanNewCommonH5(String code);
 }

+ 50 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/task/SyncPlanCommonToRedis.java

@@ -0,0 +1,50 @@
+package com.webflux.launchadmin.mysql.task;
+
+import com.alibaba.fastjson.JSONObject;
+import com.webflux.launchadmin.mysql.controller.planNew.res.PlanNewCommonRes;
+import com.webflux.launchadmin.mysql.entity.planNew.PlanNewCommon;
+import com.webflux.launchadmin.mysql.service.planNew.PlanServiceInterface;
+import com.weblux.launchredis.utils.RedisKey;
+import jakarta.annotation.Resource;
+import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.util.Objects;
+
+/**
+ * 缓存通用计划
+ *
+ * @author: wangcheng
+ * @date: 2024/7/19 17:47
+ */
+@Component
+public class SyncPlanCommonToRedis {
+    @Resource
+    private R2dbcEntityTemplate template;
+    @Resource
+    private StringRedisTemplate stringRedisTemplate;
+    @Resource
+    private PlanServiceInterface planServiceInterface;
+
+    @Scheduled(cron = "0 */1 * * * ?")
+    public void syncPlanCommon() {
+        Flux<PlanNewCommon> flux = template.select(PlanNewCommon.class).all();
+        for (PlanNewCommon one : flux.toIterable()) {
+            if (one.code().isEmpty()) {
+                continue;
+            }
+            stringRedisTemplate.opsForHash().put(RedisKey.PLAN_COMMON_INFO, one.code(), JSONObject.toJSONString(one));
+
+            // 缓存H5通用计划
+            Mono<PlanNewCommonRes> res = planServiceInterface.getPlanNewCommonH5(one.code());
+            if (res.block() == null) {
+                continue;
+            }
+            stringRedisTemplate.opsForHash().put(RedisKey.PLAN_COMMON_INFO_H5, one.code(), JSONObject.toJSONString(res.block()));
+        }
+    }
+}

+ 19 - 0
launch-common/src/main/java/com/webflux/launchcommon/utils/StringUtils.java

@@ -3,9 +3,12 @@ package com.webflux.launchcommon.utils;
 
 import org.springframework.util.AntPathMatcher;
 
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.zip.GZIPOutputStream;
 
 /**
  * 字符串工具类
@@ -449,4 +452,20 @@ public class StringUtils extends org.springframework.util.StringUtils
     {
         return (T) obj;
     }
+
+    /**
+     * GZIP 压缩数据
+     */
+    public static byte[] compressData(String data) {
+        try {
+            ByteArrayOutputStream stream = new ByteArrayOutputStream();
+            GZIPOutputStream gzipOS = new GZIPOutputStream(stream);
+            gzipOS.write(data.getBytes());
+            gzipOS.close();
+            return stream.toByteArray();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
 }

+ 6 - 0
launch-redis/src/main/java/com/weblux/launchredis/utils/RedisKey.java

@@ -32,4 +32,10 @@ public class RedisKey {
 
     /** H5客户缓存 */
     public final static String H5_USER_UNIQUE = "h5_user_unique:";
+
+    /** 通用计划缓存 */
+    public final static String PLAN_COMMON_INFO = "sync_plan_common_info";
+
+    /** 通用计划缓存H5 */
+    public final static String PLAN_COMMON_INFO_H5 = "sync_plan_common_info:h5";
 }