Pārlūkot izejas kodu

听书裂变3.0

MOKASZ\lw12420 2 gadi atpakaļ
vecāks
revīzija
e320e14ff9
37 mainītis faili ar 2618 papildinājumiem un 296 dzēšanām
  1. 139 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/ListeningPlanNewController.java
  2. 43 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/ListeningPlanNewOutController.java
  3. 29 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/H5ImageAndTextListening.java
  4. 36 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/ListeningAudioReq.java
  5. 16 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/ListeningAudioReqPage.java
  6. 39 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/ListeningAudioRes.java
  7. 34 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/ListeningDataLists.java
  8. 21 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/ListeningPlanReqPage.java
  9. 22 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/ListeningServiceGroupSettingItemRequest.java
  10. 11 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/OutListeningRequest.java
  11. 12 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/OutListeningShareRequest.java
  12. 66 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/PlanSaveReq.java
  13. 108 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/res/DataListsShare.java
  14. 67 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/res/ListeningPlanNewRes.java
  15. 13 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/res/ListeningPlanNewRes1.java
  16. 13 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/res/ListeningPlanNewRes2.java
  17. 520 273
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/PlanNewController.java
  18. 31 12
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/PlanNewOutController.java
  19. 2 2
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PlanReq.java
  20. 1 1
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PlanReqPage.java
  21. 48 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/PlanNewAllRs.java
  22. 39 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/PlanNewBackgroupPosterAllRes.java
  23. 8 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/SelectPlanRes.java
  24. 8 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/SelectPlanRes1.java
  25. 8 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/SelectPlanRes2.java
  26. 22 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/entity/listening/ListeningAudio.java
  27. 32 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/entity/listening/ListeningPlanNew.java
  28. 36 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/entity/listening/ListeningPlanNewBackgroupPoster.java
  29. 3 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/entity/planNew/Material.java
  30. 1 1
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/entity/planNew/PlanNew.java
  31. 1 1
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/entity/planNew/PlanNewBackgroupPoster.java
  32. 1066 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/service/listening/ListeningPlanServiceImpl.java
  33. 33 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/service/listening/ListeningPlanServiceInterface.java
  34. 56 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/service/planNew/PlanServiceImpl.java
  35. 19 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/service/planNew/PlanServiceInterface.java
  36. 14 5
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/service/planNew/goGenerate/GoGenerateService.java
  37. 1 1
      launch-admin/src/main/resources/application.yml

+ 139 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/ListeningPlanNewController.java

@@ -0,0 +1,139 @@
+package com.webflux.launchadmin.mysql.controller.listening;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.webflux.launchadmin.config.BaseContextHandler;
+import com.webflux.launchadmin.global.BaseException;
+import com.webflux.launchadmin.mysql.controller.listening.req.*;
+import com.webflux.launchadmin.mysql.controller.listening.res.ListeningPlanNewRes;
+import com.webflux.launchadmin.mysql.controller.planNew.req.PlanReq;
+import com.webflux.launchadmin.mysql.controller.planNew.req.PlanReqPage;
+import com.webflux.launchadmin.mysql.controller.planNew.req.ServiceGroupSettingItemRequest;
+import com.webflux.launchadmin.mysql.controller.planNew.res.PlanNewRes;
+import com.webflux.launchadmin.mysql.entity.listening.ListeningAudio;
+import com.webflux.launchadmin.mysql.entity.listening.ListeningPlanNew;
+import com.webflux.launchadmin.mysql.entity.planNew.GroupType;
+import com.webflux.launchadmin.mysql.entity.planNew.PlanNew;
+import com.webflux.launchadmin.mysql.entity.planNew.Poster;
+import com.webflux.launchadmin.mysql.entity.planNew.PosterTemplate;
+import com.webflux.launchadmin.mysql.service.listening.ListeningPlanServiceInterface;
+import com.webflux.launchadmin.mysql.service.planNew.structure.GoRequest;
+import com.webflux.launchcommon.returnObj.Paged;
+import com.webflux.launchcommon.returnObj.RStatus;
+import jakarta.annotation.Resource;
+import jakarta.validation.constraints.NotNull;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
+import org.springframework.data.relational.core.query.Criteria;
+import org.springframework.data.relational.core.query.Query;
+import org.springframework.web.bind.annotation.*;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.time.ZonedDateTime;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * 听书计划
+ * @author lw12420
+ * @date 2024/06/27
+ */
+@RestController
+@RequestMapping("in/listening")
+public class ListeningPlanNewController {
+
+    @Resource
+    private R2dbcEntityTemplate template;
+    @Resource
+    private ListeningPlanServiceInterface listeningPlanService;
+
+
+    /**
+     * 营销分类下拉(groupType)名称模糊查询
+     * @param name
+     * @return {@link Mono}<{@link RStatus}<{@link Long}>>
+     */
+//    @GetMapping("groupTypeSlt")
+//    public Mono<RStatus<List<GroupType>>> groupTypeSlt (@RequestParam("name") String name){
+//      return  listeningPlanService.groupTypeSlt(name);
+//    }
+
+    /**
+     * 复制计划
+     * @param listeningPlanNewId
+     * @return {@link Mono}<{@link RStatus}<{@link ListeningPlanNew}>>
+     */
+//    @GetMapping("copyById/{listeningPlanNewId}")
+//    public Mono<RStatus<ListeningPlanNew>> copyById (@PathVariable("listeningPlanNewId")  @NotNull Long listeningPlanNewId){
+//        return  listeningPlanService.copyById(listeningPlanNewId);
+//    }
+
+    /**
+     * 计划列表
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link Paged}<{@link PlanNew}>>>
+     */
+//    @PostMapping("planList")
+//    public Mono<RStatus<Paged<ListeningPlanNewRes>>> page(@RequestBody ListeningPlanReqPage request)   {
+//        return  listeningPlanService.page(request);
+//    }
+
+
+    /**
+     * 计划保存/修改
+     * @param saveRequest
+     * @return {@link Mono}<{@link RStatus}<{@link PlanNew}>>
+     */
+//    @PostMapping("saveOrUpdatePlan")
+//    public Mono<RStatus<ListeningPlanNew>> saveOrUpdatePlan(@RequestBody PlanSaveReq saveRequest){
+//        return  listeningPlanService.savePlan(saveRequest);
+//    }
+
+    /**
+     * 删除计划
+     * @param listeningPlanNewId
+     * @return {@link Mono}<{@link RStatus}<{@link Long}>>
+     */
+//    @DeleteMapping("deletePlanById/{listeningPlanNewId}")
+//    public Mono<RStatus<Long>> deletePlanById (@PathVariable("listeningPlanNewId")  @NotNull Long listeningPlanNewId){
+//        Mono<Long> listening_plan_new_id = template.delete(Query.query(Criteria.where("listening_plan_new_id")
+//                .is(listeningPlanNewId)), ListeningPlanNew.class);
+//        return RStatus.success(listening_plan_new_id);
+//    }
+
+    /**
+     * 听书音频保存/修改
+     * @param saveRequest
+     * @return {@link Mono}<{@link RStatus}<{@link PlanNew}>>
+     */
+    @PostMapping("saveOrUpdateAudio")
+    public Mono<RStatus<ListeningAudio>> saveOrUpdateAudio(@RequestBody ListeningAudioReq saveRequest){
+        return  listeningPlanService.saveOrUpdateAudio(saveRequest);
+    }
+
+    /**
+     * 听书音频列表
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link Paged}<{@link ListeningAudioRes}>>>
+     */
+    @PostMapping("audioList")
+    public Mono<RStatus<Paged<ListeningAudioRes>>> audioList(@RequestBody ListeningAudioReqPage request)   {
+        return  listeningPlanService.audioList(request);
+    }
+
+    /**
+     * 删除音频
+     * @param newAudioId
+     * @return {@link Mono}<{@link RStatus}<{@link Long}>>
+     */
+    @DeleteMapping("deleteAudioById/{newAudioId}")
+    public Mono<RStatus<Long>> deleteAudioById (@PathVariable("newAudioId")  @NotNull Long newAudioId){
+        Mono<Long> listening_plan_new_id = template.delete(Query.query(Criteria.where("new_audio_id")
+                .is(newAudioId)), ListeningAudio.class);
+        return RStatus.success(listening_plan_new_id);
+    }
+}

+ 43 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/ListeningPlanNewOutController.java

@@ -0,0 +1,43 @@
+package com.webflux.launchadmin.mysql.controller.listening;
+
+import com.webflux.launchadmin.mysql.controller.listening.req.*;
+import com.webflux.launchadmin.mysql.controller.listening.res.DataListsShare;
+import com.webflux.launchadmin.mysql.service.listening.ListeningPlanServiceInterface;
+import com.webflux.launchcommon.returnObj.RStatus;
+import jakarta.annotation.Resource;
+import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
+import org.springframework.web.bind.annotation.*;
+import reactor.core.publisher.Mono;
+
+/**
+ * 听书计划(h5)
+ * @author lw12420
+ * @date 2024/06/27
+ */
+@RestController
+@RequestMapping("out/listening")
+public class ListeningPlanNewOutController {
+
+    @Resource
+    private ListeningPlanServiceInterface listeningPlanService;
+
+    /**
+     * 落地页群列表
+     * @param outListeningRequest
+     * @return {@link Mono}<{@link RStatus}<{@link ListeningDataLists}>>
+     */
+    @PostMapping("landingPageList")
+    public Mono<RStatus<ListeningDataLists>> LandingPageList(@RequestBody OutListeningRequest outListeningRequest) {
+      return   listeningPlanService.LandingPageList(outListeningRequest);
+    }
+    /**
+     * 长按此处转发
+     * @param outListeningRequest
+     * @return {@link Mono}<{@link RStatus}<{@link ListeningDataLists}>>
+     */
+    @PostMapping("share")
+    public Mono<RStatus<DataListsShare>> share(@RequestBody OutListeningShareRequest outListeningRequest) {
+        return   listeningPlanService.share(outListeningRequest);
+    }
+
+}

+ 29 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/H5ImageAndTextListening.java

@@ -0,0 +1,29 @@
+package com.webflux.launchadmin.mysql.controller.listening.req;
+
+import lombok.Data;
+
+@Data
+public class H5ImageAndTextListening {
+
+    /**
+     * 群封面头像
+     */
+    private String audioImageUrl;
+    /**
+     * 群封面名称
+     */
+    private String audioName;
+  /**
+   * 音频链接
+   */
+  private String audioUrl;
+  /**
+   * 弹窗节点
+   */
+  private Integer popupNode;
+  /**
+   * 排序
+   */
+  private Integer idxNum;
+
+}

+ 36 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/ListeningAudioReq.java

@@ -0,0 +1,36 @@
+package com.webflux.launchadmin.mysql.controller.listening.req;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.springframework.data.annotation.Id;
+
+import java.time.ZonedDateTime;
+
+@Data
+public class ListeningAudioReq {
+    /**
+     * 修改必填/添加值填null
+     */
+   private Long newAudioId;
+    /**
+     * 节点
+     */
+    private String audioName;//节点
+    /**
+     * 封面图片
+     */
+    private String audioImageUrl;//封面图片
+    /**
+     * 音频链接
+     */
+    private   String audioUrl; //音频链接
+    /**
+     * 弹窗节点
+     */
+    private   Integer popupNode; //弹窗节点
+    /**
+     * 排序
+     */
+    private  Integer idxNum;//排序
+
+}

+ 16 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/ListeningAudioReqPage.java

@@ -0,0 +1,16 @@
+package com.webflux.launchadmin.mysql.controller.listening.req;
+import lombok.Data;
+
+@Data
+public class ListeningAudioReqPage {
+
+
+    private Integer page;
+    private Integer size;
+
+    /**
+     * 名称
+     */
+    private String name;
+
+}

+ 39 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/ListeningAudioRes.java

@@ -0,0 +1,39 @@
+package com.webflux.launchadmin.mysql.controller.listening.req;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.ZonedDateTime;
+
+@Data
+public class ListeningAudioRes {
+    /**
+     * 修改必填/添加值填null
+     */
+   private Long newAudioId;
+    /**
+     * 节点
+     */
+    private String audioName;//节点
+    /**
+     * 封面图片
+     */
+    private String audioImageUrl;//封面图片
+    /**
+     * 音频链接
+     */
+    private   String audioUrl; //音频链接
+    /**
+     * 弹窗节点
+     */
+    private   Integer popupNode; //弹窗节点
+    /**
+     * 排序
+     */
+    private  Integer idxNum;//排序
+
+    private   String createUser;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private ZonedDateTime createdAt;
+
+}

+ 34 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/ListeningDataLists.java

@@ -0,0 +1,34 @@
+package com.webflux.launchadmin.mysql.controller.listening.req;
+
+import com.webflux.launchadmin.mysql.controller.planNew.res.H5ImageAndText;
+import com.webflux.launchadmin.mysql.entity.listening.ListeningPlanNew;
+import com.webflux.launchadmin.mysql.entity.planNew.Ad;
+import com.webflux.launchadmin.mysql.entity.planNew.Audio;
+import com.webflux.launchadmin.mysql.entity.planNew.PlanNew;
+import com.webflux.launchadmin.mysql.entity.planNew.ReturnLoop;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class ListeningDataLists {
+    /**
+     * 计划
+     */
+    private ListeningPlanNew planNew;
+    /**
+     * 计划群数量
+     */
+    private Integer pageShow;//
+    /**
+     * 单行数量
+     */
+    private Integer pageLine;//单行数量
+    /**
+     * 群封面头像数组
+     */
+    List<H5ImageAndTextListening> images;
+
+
+
+}

+ 21 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/ListeningPlanReqPage.java

@@ -0,0 +1,21 @@
+package com.webflux.launchadmin.mysql.controller.listening.req;
+import lombok.Data;
+
+@Data
+public class ListeningPlanReqPage {
+
+
+    private Integer page;
+    private Integer size;
+
+
+    private String name; //计划名
+    private String createUser;
+    /**
+     * 值:听书裂变
+     */
+    private  String type;
+    private  String code;
+    private  Long posterTemplateId;//海报id
+
+}

+ 22 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/ListeningServiceGroupSettingItemRequest.java

@@ -0,0 +1,22 @@
+package com.webflux.launchadmin.mysql.controller.listening.req;
+import lombok.Data;
+
+@Data
+public class ListeningServiceGroupSettingItemRequest {
+    /**
+     *  保存null/字段无   修改必填
+     */
+    private   Long id;//
+    private  Long audioId;//音频id
+    private  Long groupId;//客服组id
+    private  String image;//背景组图片
+    private  String kefu;
+    private  String limitTime;//分享限时
+    private  String limitTimeRemark;//	分享限时内提示
+    private  Integer status;//0:h5链接 1:客服二维码
+    private  Integer index;//	背景图序号
+    private  String serviceGroupId;//客服组 ,分割
+    private  Integer serviceGroupType ;//1:客服组 2:上传图片
+}
+
+  

+ 11 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/OutListeningRequest.java

@@ -0,0 +1,11 @@
+package com.webflux.launchadmin.mysql.controller.listening.req;
+
+import lombok.Data;
+
+@Data
+public class OutListeningRequest {
+    private String code;
+    //private String unique;
+    //private String wxUserId;
+    //private String wx_user_id;
+}

+ 12 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/OutListeningShareRequest.java

@@ -0,0 +1,12 @@
+package com.webflux.launchadmin.mysql.controller.listening.req;
+
+import lombok.Data;
+
+@Data
+public class OutListeningShareRequest {
+    private String code;
+    private String unique;
+    private String wxUserId;
+    private String wx_user_id;
+    private Integer userVisits;
+}

+ 66 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/PlanSaveReq.java

@@ -0,0 +1,66 @@
+package com.webflux.launchadmin.mysql.controller.listening.req;
+import com.webflux.launchadmin.mysql.controller.planNew.req.ServiceGroupSettingItemRequest;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class PlanSaveReq {
+
+    /**
+     * 修改必填/添加值填null
+     */
+    private String listeningPlanNewId;
+    /**
+     * 计划名
+     */
+    private String name;
+
+    /**
+     *   值:听书裂变
+     */
+    private  Integer type;
+    /**
+     *
+     */
+    private  String code;
+    /**
+     *分类id
+     */
+    private Long  groupId; //分类id
+    /**
+     *海报id
+     */
+    @NotNull
+    private  Long posterTemplateId;//海报id
+    /**
+     *群数量
+     */
+    private  Integer pageShow;//群数量
+    /**
+     *单行数量
+     */
+    private Integer pageLine;//单行数量
+
+    /**
+     *入群链接
+     */
+    private String link;//入群链接
+
+    /**
+     *营销分类id
+     */
+    private Long backgroundGroupId;//背景组id
+
+
+    private String  baiduDot;
+
+    /**
+     * 分享背景组-配置
+     */
+    @NotEmpty
+    private List<ListeningServiceGroupSettingItemRequest> backgroupFxSetting;
+
+}

+ 108 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/res/DataListsShare.java

@@ -0,0 +1,108 @@
+package com.webflux.launchadmin.mysql.controller.listening.res;
+
+import com.webflux.launchadmin.mysql.entity.listening.ListeningPlanNew;
+import com.webflux.launchadmin.mysql.entity.listening.ListeningPlanNewBackgroupPoster;
+import com.webflux.launchadmin.mysql.entity.planNew.*;
+import lombok.Data;
+
+@Data
+public class DataListsShare {
+
+    /**
+     * 当前访问次数
+     */
+    private Integer userVisits;
+    /**
+     * 营销背景海报设置总数量
+     */
+    private Integer backgroupPosterSum;
+
+    /**
+     * 计划
+     */
+    private ListeningPlanNew planNew;
+
+    private String link;
+    /**
+     * 海报模版
+     */
+    private PosterTemplate posterTemplate;
+
+    /**
+     * 海报
+     */
+    private Poster poster;
+
+    /**
+     * 营销-配置
+     */
+    private ListeningPlanNewBackgroupPoster fxSetting;
+    /**
+     * 营销-生成图片
+     */
+    private String fxGenerateImagesUrl;
+//    /**
+//     * 清水-配置
+//     */
+//    private PlanNewBackgroupPoster qsSetting;
+
+    /**
+     * 清水-生成图片
+     */
+   // private String qsGenerateImagesUrl;
+
+    /**
+     * 音频
+     */
+    //private Audio audio;
+    /**
+     *
+     */
+
+    //private Integer redirectType;
+
+   // private  String limitTime;
+
+    //private String limitTimeRemark;
+
+    //private String spare;
+
+//
+//    /**
+//     * 列表音频
+//     */
+//    private Audio listAudio;
+//
+//    /**
+//     * 返回音频
+//     */
+//    private Audio retAudio;
+//
+//    /**
+//     *背景主任务
+//     */
+//    private BackgroupImage backgroupImage;
+//
+//    /**
+//     * 背景子任务
+//     */
+//    private List<BackgroupImageItem> backgroupImageItemList;
+//
+//    /**
+//     * 海报模版
+//     */
+//    private PosterTemplate posterTemplate;
+//
+//    /**
+//     * 海报组
+//     */
+//    private List<Poster> poster;
+//
+//    /**
+//     * 返回广告
+//     */
+//    private ReturnLoop returnLoop;
+
+
+
+}

+ 67 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/res/ListeningPlanNewRes.java

@@ -0,0 +1,67 @@
+package com.webflux.launchadmin.mysql.controller.listening.res;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.ZonedDateTime;
+
+@Data
+public class ListeningPlanNewRes {
+
+    /**
+     * 计划名
+     */
+    private String name; //计划名
+    private  String createUser;
+    //private String createId;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private  ZonedDateTime createdAt;
+  //  @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") ZonedDateTime updatedAt;
+  //  @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") ZonedDateTime deletedAt;
+    /**
+     * 听书裂变
+     */
+    private  Integer type;
+    /**
+     * code
+     */
+    private  String code;
+    /**
+     * 营销分类id
+     */
+   // private  Long  groupId; //营销分类id
+    /**
+     * 营销分类name
+     */
+    private String groupName;//营销分类name
+    /**
+     * 海报id
+     */
+    //private Long posterTemplateId;//海报id
+
+    /**
+     * 海报名称
+     */
+    private String posterTemplateName;
+    /**
+     * 群数量
+     */
+   // private  Integer pageShow;//群数量
+    /**
+     * 群数量
+     */
+   // private  Integer pageLine;//群数量
+    /**
+     * 入群链接
+     */
+   // private  String link;//入群链接
+    /**
+     * 营销背景组id
+     */
+   // private   Long backgroundGroupId;//营销背景组id
+   // private  String baiduDot;
+    /**
+     * 预览url
+     */
+    private  String previewUrl;//预览url
+}

+ 13 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/res/ListeningPlanNewRes1.java

@@ -0,0 +1,13 @@
+package com.webflux.launchadmin.mysql.controller.listening.res;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.ZonedDateTime;
+
+@Data
+public class ListeningPlanNewRes1 extends ListeningPlanNewRes {
+
+    private  String PlanNewId;
+
+}

+ 13 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/res/ListeningPlanNewRes2.java

@@ -0,0 +1,13 @@
+package com.webflux.launchadmin.mysql.controller.listening.res;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.ZonedDateTime;
+
+@Data
+public class ListeningPlanNewRes2  extends  ListeningPlanNewRes{
+
+    private  String PlanNewId;
+
+}

+ 520 - 273
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/PlanNewController.java

@@ -8,10 +8,17 @@ import cn.hutool.json.JSONUtil;
 import com.webflux.launchadmin.config.BaseContextHandler;
 import com.webflux.launchadmin.global.BaseException;
 import com.webflux.launchadmin.mysql.controller.lbOut.resp.DataList;
+import com.webflux.launchadmin.mysql.controller.listening.res.ListeningPlanNewRes;
+import com.webflux.launchadmin.mysql.controller.listening.res.ListeningPlanNewRes1;
+import com.webflux.launchadmin.mysql.controller.listening.res.ListeningPlanNewRes2;
 import com.webflux.launchadmin.mysql.controller.planNew.req.*;
 import com.webflux.launchadmin.mysql.controller.planNew.res.*;
 import com.webflux.launchadmin.mysql.entity.lb.HomePageTempItem;
+import com.webflux.launchadmin.mysql.entity.listening.ListeningPlanNew;
+import com.webflux.launchadmin.mysql.entity.listening.ListeningPlanNewBackgroupPoster;
 import com.webflux.launchadmin.mysql.entity.planNew.*;
+import com.webflux.launchadmin.mysql.service.listening.ListeningPlanServiceInterface;
+import com.webflux.launchadmin.mysql.service.planNew.PlanServiceInterface;
 import com.webflux.launchadmin.mysql.service.planNew.goGenerate.GoGenerateService;
 import com.webflux.launchadmin.mysql.service.planNew.structure.GoRequest;
 import com.webflux.launchcommon.returnObj.Paged;
@@ -26,15 +33,12 @@ import org.springframework.data.relational.core.query.Update;
 import org.springframework.web.bind.annotation.*;
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
-
 import java.time.ZonedDateTime;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
-import java.util.Optional;
-import java.util.concurrent.Phaser;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
+
 
 /**
  * 计划
@@ -50,7 +54,10 @@ public class PlanNewController {
 
     @Resource
     private GoGenerateService goGenerateService;
-
+    @Resource
+    private ListeningPlanServiceInterface listeningPlanService;
+    @Resource
+    private PlanServiceInterface planServiceInterface;
 
     @GetMapping("tt")
     public String tt(){
@@ -65,15 +72,61 @@ public class PlanNewController {
      *
      * 分享、清水背景组-回显
      * @param planNewId 计划id
-     * @param qsOrFx 1:分享 2:清水
+     * @param qsOrFx 1:营销 2:清水
      * @return {@link Mono}<{@link RStatus}<{@link BackgroupImageRes}>>
      */
-    @GetMapping("backgroupSelectOne/{planNewId}/{qsOrFx}")
-    public Mono<RStatus<List<PlanNewBackgroupPoster>>> backgroupSelectOne(@PathVariable("planNewId") Long planNewId,@PathVariable("qsOrFx") Integer qsOrFx ){
-        Mono<List<PlanNewBackgroupPoster>> listMono = template.select(Query.query(Criteria.where("plan_new_id").is(planNewId)
-                .and("qs_or_fx").is(qsOrFx)).sort(Sort.by(Sort.Order.asc("idx"))), PlanNewBackgroupPoster.class)
-                .collectList();
-        return RStatus.successList(listMono);
+    @GetMapping("backgroupSelectOne/{type}/{planNewId}/{qsOrFx}")
+    public Mono<RStatus<List<PlanNewBackgroupPosterAllRes>>> backgroupSelectOne(@PathVariable("type")  @NotNull Integer type,
+                                                                                @PathVariable("planNewId") String planNewId,@PathVariable("qsOrFx") Integer qsOrFx ){
+        if (1 == type) {
+            Mono<List<PlanNewBackgroupPosterAllRes>> listMono = template.select(Query.query(Criteria.where("plan_new_id").is(planNewId)
+                    .and("qs_or_fx").is(qsOrFx)).sort(Sort.by(Sort.Order.asc("idx"))), PlanNewBackgroupPoster.class).flatMap(request->{
+                PlanNewBackgroupPosterAllRes planNewBackgroupPosterAllRes =
+                        new PlanNewBackgroupPosterAllRes(request.id(),
+                                request.audioId(),
+                                request.groupId(),
+                                request.image(),
+                                request.kefu(),
+                                request.limitTime(),
+                                request.limitTimeRemark(),
+                                request.status(),
+                                request.index(),
+                                request.serviceGroupId(),
+                                request.serviceGroupType(),
+                                qsOrFx,
+                                ZonedDateTime.now(),
+                                null,
+                                null,
+                                request.planNewId(), null, null);
+                return Mono.just(planNewBackgroupPosterAllRes);
+            }).collectList();
+            return RStatus.successList(listMono);
+        } else if (2 == type) {
+            Mono<List<PlanNewBackgroupPosterAllRes>> listMono = template.select(Query.query(Criteria.where("listening_plan_new_id").is(planNewId)
+                    .and("qs_or_fx").is(qsOrFx))
+                    .sort(Sort.by(Sort.Order.asc("idx"))), ListeningPlanNewBackgroupPoster.class).flatMap(request->{
+                PlanNewBackgroupPosterAllRes planNewBackgroupPosterAllRes =
+                        new PlanNewBackgroupPosterAllRes(request.id(),
+                                request.audioId(),
+                                request.groupId(),
+                                request.image(),
+                                request.kefu(),
+                                request.limitTime(),
+                                request.limitTimeRemark(),
+                                request.status(),
+                                request.index(),
+                                request.serviceGroupId(),
+                                request.serviceGroupType(),
+                                qsOrFx,
+                                ZonedDateTime.now(),
+                                null,
+                                null,
+                                request.listeningPlanNewId(), null, null);
+                return Mono.just(planNewBackgroupPosterAllRes);
+            }).collectList();
+            return RStatus.successList(listMono);
+        }
+            throw new BaseException("type异常");
     }
 
     /**
@@ -146,7 +199,6 @@ public class PlanNewController {
      */
     @GetMapping("backgroupSlt")
     public Mono<RStatus<List<BackgroupImage>>> backgroupSlt ( @RequestParam("name") String name,@RequestParam("groupType") String groupType){
-
         Criteria criteria= Criteria.where("group_type").is(groupType) ; //poster_template_id
         if (Objects.nonNull(name) && "" != name) {
             criteria = criteria.and("name").like("%"+name+"%");
@@ -176,19 +228,16 @@ public class PlanNewController {
      */
     @PostMapping("savePoster")
     public Mono<RStatus<Poster>> savePoster(@RequestBody PosterRequest posterRequset){
-
         return goGenerateService.savePoster(posterRequset);
     }
     @PostMapping("test11")
     public Mono<RStatus<Poster>> test11(){
         return goGenerateService.updatePoster1();
-
     }
     @PostMapping("test12")
     public Mono<String> test112(){
         String string = RandomUtil.randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6);
         return Mono.just(string);//goGenerateService.updatePoster12();
-
     }
     /**
      * 海报修改
@@ -348,86 +397,109 @@ public class PlanNewController {
      * @return {@link Mono}<{@link RStatus}<{@link PlanNew}>>
      */
     @PostMapping("savePlan")
-    public Mono<RStatus<PlanNew>> savePlan(@RequestBody PlanReq saveRequest){
-        String userName = BaseContextHandler.getUserName();
-        String userId = BaseContextHandler.getUserId();
-        saveRequest.setCode(IdUtil.fastSimpleUUID());
-        Long posterTemplateId = saveRequest.getPosterTemplateId();
-        Mono<String> stringMono1 = template
-                .select(Query.query(Criteria.where("poster_template_id").is(posterTemplateId)).sort(Sort.by(Sort.Order.asc("created_at"))), Poster.class)
-                .collectList().flatMap(f -> {
-                    Poster poster = f.get(0);
-                    String posterTemplate = poster.posterTemplate();
-                    JSONObject jsonObject = JSONUtil.parseObj(posterTemplate);
-                    GoRequest goRequest = new GoRequest();
-                    BeanUtil.copyProperties(jsonObject, goRequest);
-                    ServiceGroupSettingItemRequest serviceGroupSettingItemRequest = saveRequest.getBackgroupFxSetting().get(0);
-                    Mono<String> stringMono = goGenerateService.saveAndUpdatePlanGenerateImage0(goRequest,
-                            goGenerateService.getStringBuilderMono(goRequest),
-                            serviceGroupSettingItemRequest,
-                            saveRequest);
-                    return stringMono;
-                });
-        Mono<StringBuilder> stringBuilderMono ;
-        if(saveRequest.getRedirectType()==2){
-           stringBuilderMono =Mono.just(new StringBuilder()); //goGenerateService.byPlanNewIdGetUrl(saveRequest.getRedirectPlanId());
-        }else {
-            stringBuilderMono=Mono.just(new StringBuilder(saveRequest.getLink()));
-        }
-    Mono<PlanNew> insert = Mono.zip(stringMono1, stringBuilderMono).flatMap(f->{
-            PlanNew plan = new PlanNew(null,
-                    saveRequest.getName(),
-                    userName,
-                    userId,
-                    ZonedDateTime.now(),
-                    ZonedDateTime.now(),
-                    null,
-                    saveRequest.getType(),
-                    saveRequest.getCode(),
-                    saveRequest.getGroupId(),
-                    saveRequest.getPosterTemplateId(),
-                    saveRequest.getPageShow(),
-                    saveRequest.getPageLine(),
-                    saveRequest.getCount(),
-                    saveRequest.getListAudioId(),
-                    saveRequest.getRetAudioId(),
-                    f.getT2().toString(),
-                    saveRequest.getIsAddQun(),
-                    saveRequest.getBackgroundGroupId(),
-                    saveRequest.getHomePageId(),
-                    saveRequest.getTopAdvNum(),
-                    saveRequest.getBottomAdvNum(),
-                    saveRequest.getReturnLoopId(),
-                    saveRequest.getBackgroundGroupQsId(),
-                    saveRequest.getTopAdvBl(),
-                    saveRequest.getBottomAdvBl(),
-                    saveRequest.getReturnLoopBl(),
-                    saveRequest.getGroupIdQs(),
-                    saveRequest.getBaiduDot(),
-                    saveRequest.getBackgroundGroupIdNewAdd(),
-                    f.getT1(),
-                    saveRequest.getRedirectType(),
-                    saveRequest.getRedirectPlanId()
-            );
-            return template.insert(plan);
-
-    });
-        Mono<PlanNew> map = insert.map(f -> {
-            List<ServiceGroupSettingItemRequest> backgroupFxSetting = saveRequest.getBackgroupFxSetting();
-            backgroupFxSetting.forEach(fx -> {
-                fxBackgroupSettingsSave(fx, f.planNewId(), 1);
+    public Mono<RStatus<String>> savePlan(@RequestBody PlanReq saveRequest){
+        if(2==saveRequest.getType()){
+            return   listeningPlanService.savePlan(saveRequest);
+        }else if(1==saveRequest.getType()){
+            String userName = BaseContextHandler.getUserName();
+            String userId = BaseContextHandler.getUserId();
+            saveRequest.setCode(IdUtil.fastSimpleUUID());
+            Long posterTemplateId = saveRequest.getPosterTemplateId();
+            Mono<String> stringMono1 = template
+                    .select(Query.query(Criteria.where("poster_template_id")
+                            .is(posterTemplateId))
+                            .sort(Sort.by(Sort.Order.asc("created_at"))), Poster.class)
+                    .collectList().flatMap(f -> {
+                        Poster poster = f.get(0);
+                        String posterTemplate = poster.posterTemplate();
+                        JSONObject jsonObject = JSONUtil.parseObj(posterTemplate);
+                        GoRequest goRequest = new GoRequest();
+                        BeanUtil.copyProperties(jsonObject, goRequest);
+                        ServiceGroupSettingItemRequest serviceGroupSettingItemRequest = saveRequest.getBackgroupFxSetting().get(0);
+                        Mono<String> stringMono = goGenerateService.saveAndUpdatePlanGenerateImage0(goRequest,
+                                goGenerateService.getStringBuilderMono(goRequest),
+                                serviceGroupSettingItemRequest,
+                                saveRequest);
+                        return stringMono;
+                    });
+            Mono<StringBuilder> stringBuilderMono ;
+            if(saveRequest.getRedirectType()==2){
+                stringBuilderMono =Mono.just(new StringBuilder()); //goGenerateService.byPlanNewIdGetUrl(saveRequest.getRedirectPlanId());
+            }else {
+                stringBuilderMono=Mono.just(new StringBuilder(saveRequest.getLink()));
+            }
+            Mono<PlanNew> insert = Mono.zip(stringMono1, stringBuilderMono).flatMap(f->{
+                PlanNew plan = new PlanNew(IdUtil.fastSimpleUUID(),
+                        saveRequest.getName(),
+                        userName,
+                        userId,
+                        ZonedDateTime.now(),
+                        ZonedDateTime.now(),
+                        null,
+                        saveRequest.getType(),
+                        saveRequest.getCode(),
+                        saveRequest.getGroupId(),
+                        saveRequest.getPosterTemplateId(),
+                        saveRequest.getPageShow(),
+                        saveRequest.getPageLine(),
+                        saveRequest.getCount(),
+                        saveRequest.getListAudioId(),
+                        saveRequest.getRetAudioId(),
+                        f.getT2().toString(),
+                        saveRequest.getIsAddQun(),
+                        saveRequest.getBackgroundGroupId(),
+                        saveRequest.getHomePageId(),
+                        saveRequest.getTopAdvNum(),
+                        saveRequest.getBottomAdvNum(),
+                        saveRequest.getReturnLoopId(),
+                        saveRequest.getBackgroundGroupQsId(),
+                        saveRequest.getTopAdvBl(),
+                        saveRequest.getBottomAdvBl(),
+                        saveRequest.getReturnLoopBl(),
+                        saveRequest.getGroupIdQs(),
+                        saveRequest.getBaiduDot(),
+                        saveRequest.getBackgroundGroupIdNewAdd(),
+                        f.getT1(),
+                        saveRequest.getRedirectType(),
+                        saveRequest.getRedirectPlanId()
+                );
+                return template.insert(plan);
             });
-            List<ServiceGroupSettingItemRequest> backgroupQsSetting = saveRequest.getBackgroupQsSetting();
-            backgroupQsSetting.forEach(qs -> {
-                fxBackgroupSettingsSave(qs, f.planNewId(), 2);
+            Mono<String> map = insert.flatMap(f -> {
+                Flux<PlanNewBackgroupPoster> just = getPlanNewBackgroupPosterFlux(saveRequest, f);
+                return  Mono.zip(batchInsert(just), Mono.just(f)).flatMap(ff -> {
+                    PlanNew t2 = ff.getT2();
+                    return Mono.just(t2.planNewId());
+                });
             });
-            return f;
+            return  RStatus.success(map);
+        }
+      throw new BaseException("type类型错误");
+    }
+
+    private Flux<PlanNewBackgroupPoster> getPlanNewBackgroupPosterFlux(PlanReq saveRequest, PlanNew f) {
+        List<ServiceGroupSettingItemRequest> backgroupFxSetting = saveRequest.getBackgroupFxSetting();
+        ArrayList<PlanNewBackgroupPoster> listeningPlanNewBackgroupPosters = new ArrayList<>();
+        backgroupFxSetting.forEach(fx -> {
+            PlanNewBackgroupPoster listeningPlanNewBackgroupPoster = fxBackgroupSettingsSave(fx, f.planNewId(), 1);
+            listeningPlanNewBackgroupPosters.add(listeningPlanNewBackgroupPoster);
+        });
+        List<ServiceGroupSettingItemRequest> backgroupQsSetting = saveRequest.getBackgroupQsSetting();
+        backgroupQsSetting.forEach(fx -> {
+            PlanNewBackgroupPoster listeningPlanNewBackgroupPoster = fxBackgroupSettingsSave(fx, f.planNewId(), 2);
+            listeningPlanNewBackgroupPosters.add(listeningPlanNewBackgroupPoster);
         });
-        return  RStatus.success(map);
+        Flux<PlanNewBackgroupPoster> just = Flux.fromIterable(listeningPlanNewBackgroupPosters);
+        return just;
     }
 
-    public Boolean fxBackgroupSettingsSave( ServiceGroupSettingItemRequest request,Long planNewId,Integer qsOrFx){
-        PlanNewBackgroupPoster planNewBackgroupPoster = new PlanNewBackgroupPoster(null,
+    public Mono<List<PlanNewBackgroupPoster>> batchInsert(Flux<PlanNewBackgroupPoster> entities) {
+        Mono<List<PlanNewBackgroupPoster>> listMono = entities.flatMap(entity -> template
+                .insert(PlanNewBackgroupPoster.class).using(entity)).collectList();
+        return listMono;
+    }
+    public PlanNewBackgroupPoster fxBackgroupSettingsSave( ServiceGroupSettingItemRequest request,String planNewId,Integer qsOrFx){
+         return new PlanNewBackgroupPoster(null,
                 request.getAudioId(),
                 request.getGroupId(),
                 request.getImage(),
@@ -443,11 +515,11 @@ public class PlanNewController {
                 null,
                 null,
                 planNewId,null,null);
-         template.insert(planNewBackgroupPoster).subscribe(f->{
-             JSONObject jsonObject = JSONUtil.parseObj(f);
-             System.out.println(jsonObject);
-         });
-        return true;
+//         template.insert(planNewBackgroupPoster).subscribe(f->{
+//             JSONObject jsonObject = JSONUtil.parseObj(f);
+//             System.out.println(jsonObject);
+//         });
+
     }
 
 
@@ -457,83 +529,96 @@ public class PlanNewController {
      * @return {@link Mono}<{@link RStatus}<{@link PlanNew}>>
      */
     @PostMapping("updatePlan")
-    public Mono<RStatus<PlanNew>> updatePlan(@RequestBody PlanReq saveRequest){
-        Long posterTemplateId = saveRequest.getPosterTemplateId();
-        Mono<String> stringMono1 = template
-                .select(Query.query(Criteria.where("poster_template_id").is(posterTemplateId)).sort(Sort.by(Sort.Order.asc("created_at"))), Poster.class)
-                .collectList().flatMap(f -> {
-                    Poster poster = f.get(0);
-                    String posterTemplate = poster.posterTemplate();
-                    JSONObject jsonObject = JSONUtil.parseObj(posterTemplate);
-                    GoRequest goRequest = new GoRequest();
-                    BeanUtil.copyProperties(jsonObject, goRequest);
-                    ServiceGroupSettingItemRequest serviceGroupSettingItemRequest = saveRequest.getBackgroupFxSetting().get(0);
-                    Mono<String> stringMono = goGenerateService.saveAndUpdatePlanGenerateImage0(goRequest,
-                            goGenerateService.getStringBuilderMono(goRequest), serviceGroupSettingItemRequest, saveRequest);
-                    return stringMono;
+    public Mono<RStatus<String>> updatePlan(@RequestBody PlanReq saveRequest){
+        if(2==saveRequest.getType()){
+            return   listeningPlanService.savePlan(saveRequest);
+        }else if(1==saveRequest.getType()){
+            Long posterTemplateId = saveRequest.getPosterTemplateId();
+            Mono<String> stringMono1 = template
+                    .select(Query.query(Criteria.where("poster_template_id").is(posterTemplateId)).sort(Sort.by(Sort.Order.asc("created_at"))), Poster.class)
+                    .collectList().flatMap(f -> {
+                        Poster poster = f.get(0);
+                        String posterTemplate = poster.posterTemplate();
+                        JSONObject jsonObject = JSONUtil.parseObj(posterTemplate);
+                        GoRequest goRequest = new GoRequest();
+                        BeanUtil.copyProperties(jsonObject, goRequest);
+                        ServiceGroupSettingItemRequest serviceGroupSettingItemRequest = saveRequest.getBackgroupFxSetting().get(0);
+                        Mono<String> stringMono = goGenerateService.saveAndUpdatePlanGenerateImage0(goRequest,
+                                goGenerateService.getStringBuilderMono(goRequest), serviceGroupSettingItemRequest, saveRequest);
+                        return stringMono;
+                    });
+            Mono<PlanNew> plan_new_id1 = template.selectOne(Query.query(Criteria.where("plan_new_id").is(saveRequest.getPlanNewId())), PlanNew.class);
+            Mono<StringBuilder> stringBuilderMono ;
+            if(saveRequest.getRedirectType()==2){
+                stringBuilderMono = Mono.just(new StringBuilder(""));//goGenerateService.byPlanNewIdGetUrl(saveRequest.getRedirectPlanId());
+            }else {
+                stringBuilderMono=Mono.just(new StringBuilder(saveRequest.getLink()));
+            }
+            Mono<PlanNew> planNewMono = Mono.zip(stringMono1, plan_new_id1, stringBuilderMono).flatMap(f -> {
+                PlanNew map = f.getT2();
+                PlanNew planNew = new PlanNew(
+                       saveRequest.getPlanNewId(),
+                        saveRequest.getName(),
+                        map.createUser(),
+                        map.createId(),
+                        map.createdAt(),
+                        ZonedDateTime.now(),
+                        map.deletedAt(),
+                        saveRequest.getType(),
+                        map.code(),
+                        saveRequest.getGroupId(),
+                        saveRequest.getPosterTemplateId(),
+                        saveRequest.getPageShow(),
+                        saveRequest.getPageLine(),
+                        saveRequest.getCount(),
+                        saveRequest.getListAudioId(),
+                        saveRequest.getRetAudioId(),
+                        f.getT3().toString(),
+                        saveRequest.getIsAddQun(),
+                        saveRequest.getBackgroundGroupId(),
+                        saveRequest.getHomePageId(),
+                        saveRequest.getTopAdvNum(),
+                        saveRequest.getBottomAdvNum(),
+                        saveRequest.getReturnLoopId(),
+                        saveRequest.getBackgroundGroupQsId(),
+                        saveRequest.getTopAdvBl(),
+                        saveRequest.getBottomAdvBl(),
+                        saveRequest.getReturnLoopBl(),
+                        saveRequest.getGroupIdQs(),
+                        saveRequest.getBaiduDot(),
+                        saveRequest.getBackgroundGroupIdNewAdd(),
+                        f.getT1(),
+                        saveRequest.getRedirectType(),
+                        saveRequest.getRedirectPlanId()
+                );
+                return Mono.just(planNew);
+            }).flatMap(template::update);
+
+//            Mono<String> map = planNewMono.map(f->{
+//                template.delete(Query.query(Criteria.where("plan_new_id").is(f.planNewId())),PlanNewBackgroupPoster.class).subscribe();
+//                return f;
+//            }).map(f -> {
+//                List<ServiceGroupSettingItemRequest> backgroupFxSetting = saveRequest.getBackgroupFxSetting();
+//                backgroupFxSetting.forEach(fx -> fxBackgroupSettingsUpdate(fx, f.planNewId(), 1));
+//                List<ServiceGroupSettingItemRequest> backgroupQsSetting = saveRequest.getBackgroupQsSetting();
+//                backgroupQsSetting.forEach(qs -> fxBackgroupSettingsUpdate(qs, f.planNewId(), 2));
+//                return f.planNewId()+"";
+//            });
+
+            Mono<String> map = planNewMono.flatMap(f -> {
+                Flux<PlanNewBackgroupPoster> just = getPlanNewBackgroupPosterFlux(saveRequest, f);
+                Mono<Long>  ml= template.delete(Query.query(Criteria.where("plan_new_id").is(f.planNewId())),PlanNewBackgroupPoster.class);
+                return  Mono.zip(batchInsert(just), Mono.just(f),ml).flatMap(ff -> {
+                    PlanNew t2 = ff.getT2();
+                    return Mono.just(t2.planNewId());
                 });
-        Mono<PlanNew> plan_new_id1 = template.selectOne(Query.query(Criteria.where("plan_new_id").is(saveRequest.getPlanNewId())), PlanNew.class);
-
-        Mono<StringBuilder> stringBuilderMono ;
-        if(saveRequest.getRedirectType()==2){
-            stringBuilderMono = Mono.just(new StringBuilder(""));//goGenerateService.byPlanNewIdGetUrl(saveRequest.getRedirectPlanId());
-        }else {
-            stringBuilderMono=Mono.just(new StringBuilder(saveRequest.getLink()));
+            });
+            return RStatus.success(map);
         }
-        Mono<PlanNew> planNewMono = Mono.zip(stringMono1, plan_new_id1, stringBuilderMono).flatMap(f -> {
-            PlanNew map = f.getT2();
-            PlanNew planNew = new PlanNew(
-                    saveRequest.getPlanNewId(),
-                    saveRequest.getName(),
-                    map.createUser(),
-                    map.createId(),
-                    map.createdAt(),
-                    ZonedDateTime.now(),
-                    map.deletedAt(),
-                    saveRequest.getType(),
-                    map.code(),
-                    saveRequest.getGroupId(),
-                    saveRequest.getPosterTemplateId(),
-                    saveRequest.getPageShow(),
-                    saveRequest.getPageLine(),
-                    saveRequest.getCount(),
-                    saveRequest.getListAudioId(),
-                    saveRequest.getRetAudioId(),
-                    f.getT3().toString(),
-                    saveRequest.getIsAddQun(),
-                    saveRequest.getBackgroundGroupId(),
-                    saveRequest.getHomePageId(),
-                    saveRequest.getTopAdvNum(),
-                    saveRequest.getBottomAdvNum(),
-                    saveRequest.getReturnLoopId(),
-                    saveRequest.getBackgroundGroupQsId(),
-                    saveRequest.getTopAdvBl(),
-                    saveRequest.getBottomAdvBl(),
-                    saveRequest.getReturnLoopBl(),
-                    saveRequest.getGroupIdQs(),
-                    saveRequest.getBaiduDot(),
-                    saveRequest.getBackgroundGroupIdNewAdd(),
-                    f.getT1(),
-                    saveRequest.getRedirectType(),
-                    saveRequest.getRedirectPlanId()
-            );
-            return Mono.just(planNew);
-        }).flatMap(template::update);
-
-        Mono<PlanNew> map = planNewMono.map(f->{
-            template.delete(Query.query(Criteria.where("plan_new_id").is(f.planNewId())),PlanNewBackgroupPoster.class).subscribe();
-            return f;
-        }).map(f -> {
-            List<ServiceGroupSettingItemRequest> backgroupFxSetting = saveRequest.getBackgroupFxSetting();
-            backgroupFxSetting.forEach(fx -> fxBackgroupSettingsUpdate(fx, f.planNewId(), 1));
-            List<ServiceGroupSettingItemRequest> backgroupQsSetting = saveRequest.getBackgroupQsSetting();
-            backgroupQsSetting.forEach(qs -> fxBackgroupSettingsUpdate(qs, f.planNewId(), 2));
-            return f;
-        });
-        return RStatus.success(map);
 
+        throw new BaseException("type类型错误");
     }
-    public void fxBackgroupSettingsUpdate( ServiceGroupSettingItemRequest request,Long planNewId,Integer qsOrFx){
+    public void fxBackgroupSettingsUpdate( ServiceGroupSettingItemRequest request,String planNewId,Integer qsOrFx){
         PlanNewBackgroupPoster planNewBackgroupPoster = new PlanNewBackgroupPoster(request.getId(),
                 request.getAudioId(),
                 request.getGroupId(),
@@ -558,50 +643,88 @@ public class PlanNewController {
      * @param planNewId
      * @return {@link Mono}<{@link RStatus}<{@link PlanNew}>>
      */
-    @GetMapping("copyById/{planNewId}")
-    public Mono<RStatus<PlanNew>> copyById (@PathVariable("planNewId")  @NotNull Long planNewId){
-        String userName = BaseContextHandler.getUserName();
-        String userId = BaseContextHandler.getUserId();
-        Mono<PlanNew> plan_new_id = template.selectOne(Query.query(Criteria.where("plan_new_id").is(planNewId)), PlanNew.class)
-                .map(saveRequest -> new PlanNew(null,
-                        saveRequest.name(),
-                        userName,
-                        userId,
-                        ZonedDateTime.now(),
-                        ZonedDateTime.now(),
-                        null,
-                        saveRequest.type(),
-                        IdUtil.fastSimpleUUID(),
-                        saveRequest.groupId(),
-                        saveRequest.posterTemplateId(),
-                        saveRequest.pageShow(),
-                        saveRequest.pageLine(),
-                        saveRequest.count(),
-                        saveRequest.listAudioId(),
-                        saveRequest.retAudioId(),
-                        saveRequest.link(),
-                        saveRequest.isAddQun(),
-                        saveRequest.backgroundGroupId(),
-                        saveRequest.homePageId(),
-                        saveRequest.topAdvNum(),
-                        saveRequest.bottomAdvNum(),
-                        saveRequest.returnLoopId(),
-                        saveRequest.backgroundGroupQsId(),
-                        saveRequest.topAdvBl(),
-                        saveRequest.bottomAdvBl(),
-                        saveRequest.returnLoopBl(),
-                        saveRequest.groupIdQs(),
-                        saveRequest.baiduDot(),
-                        saveRequest.backgroundGroupIdNewAdd(),
-                        saveRequest.previewUrl(),
-                        saveRequest.redirectType(),
-                        saveRequest.redirectPlanId()
-                )).flatMap(map -> {
-                    System.out.println(map.createUser());
-                    System.out.println(JSONUtil.toJsonStr(map));
-                    return template.insert(map);
-                });
-        return RStatus.success(plan_new_id);
+    @GetMapping("copyById/{type}/{planNewId}")
+    public Mono<RStatus<String>> copyById (@PathVariable("type")  @NotNull Integer type,@PathVariable("planNewId")  @NotNull String planNewId){
+        if (2 == type) {
+             return listeningPlanService.copyById(planNewId);
+        }else if (1==type){
+            String userName = BaseContextHandler.getUserName();
+            String userId = BaseContextHandler.getUserId();
+            Mono<PlanNew> plan_new_id = template.selectOne(Query.query(Criteria.where("plan_new_id").is(planNewId)), PlanNew.class)
+                    .map(saveRequest -> new PlanNew(IdUtil.fastSimpleUUID(),
+                            saveRequest.name(),
+                            userName,
+                            userId,
+                            ZonedDateTime.now(),
+                            ZonedDateTime.now(),
+                            null,
+                            saveRequest.type(),
+                            IdUtil.fastSimpleUUID(),
+                            saveRequest.groupId(),
+                            saveRequest.posterTemplateId(),
+                            saveRequest.pageShow(),
+                            saveRequest.pageLine(),
+                            saveRequest.count(),
+                            saveRequest.listAudioId(),
+                            saveRequest.retAudioId(),
+                            saveRequest.link(),
+                            saveRequest.isAddQun(),
+                            saveRequest.backgroundGroupId(),
+                            saveRequest.homePageId(),
+                            saveRequest.topAdvNum(),
+                            saveRequest.bottomAdvNum(),
+                            saveRequest.returnLoopId(),
+                            saveRequest.backgroundGroupQsId(),
+                            saveRequest.topAdvBl(),
+                            saveRequest.bottomAdvBl(),
+                            saveRequest.returnLoopBl(),
+                            saveRequest.groupIdQs(),
+                            saveRequest.baiduDot(),
+                            saveRequest.backgroundGroupIdNewAdd(),
+                            saveRequest.previewUrl(),
+                            saveRequest.redirectType(),
+                            saveRequest.redirectPlanId()
+                    )).flatMap(map -> template.insert(map));
+            Mono<List<PlanNewBackgroupPoster>> listening_plan_new_id1 =
+                    template.select(Query.query(Criteria.where("plan_new_id")
+                            .is(planNewId)), PlanNewBackgroupPoster.class)
+                            .collectList();
+            Mono<String> stringMono = Mono.zip(plan_new_id, listening_plan_new_id1).flatMap(f -> {
+                PlanNew t1 = f.getT1();
+                List<PlanNewBackgroupPoster> t2 = f.getT2();
+                if (!t2.isEmpty()) {
+                    List<PlanNewBackgroupPoster> collect = t2.stream().map(request -> new PlanNewBackgroupPoster(null,
+                            request.audioId(),
+                            request.groupId(),
+                            request.image(),
+                            request.kefu(),
+                            request.limitTime(),
+                            request.limitTimeRemark(),
+                            request.status(),
+                            request.index(),
+                            request.serviceGroupId(),
+                            request.serviceGroupType(),
+                            request.qsOrFx(),
+                            ZonedDateTime.now(),
+                            null,
+                            null,
+                            t1.planNewId(),
+                            request.generateImagesJson(),
+                            request.generateImagesUrl())).collect(Collectors.toList());
+                    Mono<List<PlanNewBackgroupPoster>> listMono =
+                            Flux.fromIterable(collect).flatMap(entity -> template.insert(entity)).collectList();
+                    return Mono.zip(Mono.just(t1), listMono).flatMap(ff -> {
+                        PlanNew t11 = ff.getT1();
+                        return Mono.just(t11.planNewId());
+                    });
+                } else {
+                    return Mono.just(t1.planNewId());
+                }
+            });
+            return RStatus.success(stringMono);
+        }
+        throw new BaseException("type类型错误");
+
     }
 
     /**
@@ -609,10 +732,31 @@ public class PlanNewController {
      * @param planNewId
      * @return {@link Mono}<{@link RStatus}<{@link Long}>>
      */
-    @DeleteMapping("deleteById/{planNewId}")
-    public Mono<RStatus<Long>> deleteById (@PathVariable("planNewId")  @NotNull Long planNewId){
-        Mono<Long> plan_new_id = template.delete(Query.query(Criteria.where("plan_new_id").is(planNewId)), PlanNew.class);
-        return RStatus.success(plan_new_id);
+    @DeleteMapping("deleteById/{type}/{planNewId}")
+    public Mono<RStatus<Long>> deleteById (@PathVariable("type")  @NotNull Integer type,@PathVariable("planNewId")  @NotNull String planNewId ){
+        if(1==type){
+            Query plan_new_id2 = Query.query(Criteria.where("plan_new_id").is(planNewId));
+            Mono<Long> plan_new_id = template.delete(plan_new_id2, PlanNew.class)
+                    .switchIfEmpty(Mono.error(new BaseException("计划id异常"))) //Mono.error(new BaseException("查询海报模版 id:"+f.posterTemplateId()+"=>空"))
+                    .onErrorResume(throwable -> Mono.error(new Exception("删除计划 " +planNewId+"---"+ type+"error:" + throwable.getMessage())));
+            Mono<Long> plan_new_id1 = template.count(plan_new_id2, PlanNewBackgroupPoster.class).filter(f -> f > 0)
+                    .flatMap(f -> template.delete(plan_new_id2, PlanNewBackgroupPoster.class))
+                    .switchIfEmpty(Mono.just(0L));
+            Mono<Long> longMono = Mono.zip(plan_new_id1, plan_new_id).flatMap(f -> Mono.just(f.getT1()));
+            return RStatus.success(longMono);
+        }else if(2==type) {
+            Query listening_plan_new_id1 = Query.query(Criteria.where("listening_plan_new_id")
+                    .is(planNewId));
+            Mono<Long> listening_plan_new_id = template.delete(listening_plan_new_id1, ListeningPlanNew.class)
+                    .switchIfEmpty(Mono.error(new BaseException("计划id异常"))) //Mono.error(new BaseException("查询海报模版 id:"+f.posterTemplateId()+"=>空"))
+                    .onErrorResume(throwable -> Mono.error(new Exception("删除计划 " +planNewId+"---"+ type+"error:" + throwable.getMessage())));
+            Mono<Long> plan_new_id1 = template.count(listening_plan_new_id1, ListeningPlanNewBackgroupPoster.class).filter(f -> f > 0)
+                    .flatMap(f -> template.delete(listening_plan_new_id1, ListeningPlanNewBackgroupPoster.class))
+                    .switchIfEmpty(Mono.just(0L));
+            Mono<Long> longMono = Mono.zip(listening_plan_new_id, plan_new_id1).flatMap(f -> Mono.just(f.getT1()));
+            return RStatus.success(longMono);
+        }
+        throw new BaseException("type类型错误");
     }
 
     /**
@@ -620,10 +764,94 @@ public class PlanNewController {
      * @param planNewId
      * @return
      */
-    @GetMapping("planNewInfo/{planNewId}")
-    public Mono<RStatus<PlanNew>> planNewInfo(@PathVariable("planNewId")  @NotNull Long planNewId){
-        Mono<PlanNew> planNewMono = template.selectOne(Query.query(Criteria.where("plan_new_id").is(planNewId)), PlanNew.class);
-        return RStatus.success(planNewMono);
+    @GetMapping("planNewInfo/{type}/{planNewId}")
+    public Mono<RStatus<PlanNewAllRs>> planNewInfo(@PathVariable("type")  @NotNull Integer type,@PathVariable("planNewId")  @NotNull String planNewId){
+        if (1 == type) {
+            Mono<PlanNewAllRs> planNewAllRsMono = template.selectOne(Query.query(Criteria.where("plan_new_id").is(planNewId)), PlanNew.class)
+                    .flatMap(saveRequest -> {
+                                PlanNewAllRs planNewAllRs = new PlanNewAllRs(saveRequest.planNewId(),
+                                        saveRequest.name(),
+                                        saveRequest.createUser(),
+                                        saveRequest.createId(),
+                                        ZonedDateTime.now(),
+                                        ZonedDateTime.now(),
+                                        null,
+                                        saveRequest.type(),
+                                        saveRequest.code(),
+                                        saveRequest.groupId(),
+                                        saveRequest.posterTemplateId(),
+                                        saveRequest.pageShow(),
+                                        saveRequest.pageLine(),
+                                        saveRequest.count(),
+                                        saveRequest.listAudioId(),
+                                        saveRequest.retAudioId(),
+                                        saveRequest.link(),
+                                        saveRequest.isAddQun(),
+                                        saveRequest.backgroundGroupId(),
+                                        saveRequest.homePageId(),
+                                        saveRequest.topAdvNum(),
+                                        saveRequest.bottomAdvNum(),
+                                        saveRequest.returnLoopId(),
+                                        saveRequest.backgroundGroupQsId(),
+                                        saveRequest.topAdvBl(),
+                                        saveRequest.bottomAdvBl(),
+                                        saveRequest.returnLoopBl(),
+                                        saveRequest.groupIdQs(),
+                                        saveRequest.baiduDot(),
+                                        saveRequest.backgroundGroupIdNewAdd(),
+                                        saveRequest.previewUrl(),
+                                        saveRequest.redirectType(),
+                                        saveRequest.redirectPlanId()
+                                );
+                                return Mono.just(planNewAllRs);
+                            }
+                    ).switchIfEmpty(Mono.error(new BaseException("计划id异常"))) //Mono.error(new BaseException("查询海报模版 id:"+f.posterTemplateId()+"=>空"))
+                    .onErrorResume(throwable -> Mono.error(new Exception("计划id异常")));
+            return RStatus.success(planNewAllRsMono);
+        }else if (2 == type) {
+            Mono<PlanNewAllRs> planNewAllRsMono = template.selectOne(Query.query(Criteria.where("plan_new_id").is(planNewId)), ListeningPlanNew.class)
+                    .flatMap(saveRequest -> {
+                                PlanNewAllRs planNewAllRs = new PlanNewAllRs(saveRequest.listeningPlanNewId(),
+                                        saveRequest.name(),
+                                        saveRequest.createUser(),
+                                        saveRequest.createId(),
+                                        ZonedDateTime.now(),
+                                        ZonedDateTime.now(),
+                                        null,
+                                        saveRequest.type(),
+                                        saveRequest.code(),
+                                        saveRequest.groupId(),
+                                        saveRequest.posterTemplateId(),
+                                        saveRequest.pageShow(),
+                                        saveRequest.pageLine(),
+                                        null,
+                                        null,
+                                        null,
+                                        saveRequest.link(),
+                                        null,
+                                        saveRequest.backgroundGroupId(),
+                                        null,
+                                        null,
+                                        null,
+                                        null,
+                                        null,
+                                        null,
+                                        null,
+                                        null,
+                                        null,
+                                        saveRequest.baiduDot(),
+                                        null,
+                                        saveRequest.previewUrl(),
+                                        null,
+                                        null
+                                );
+                                return Mono.just(planNewAllRs);
+                            }
+                    ).switchIfEmpty(Mono.error(new BaseException("计划id异常"))) //Mono.error(new BaseException("查询海报模版 id:"+f.posterTemplateId()+"=>空"))
+                    .onErrorResume(throwable -> Mono.error(new Exception("计划id异常")));
+            return RStatus.success(planNewAllRsMono);
+        }
+        throw new BaseException("type类型错误");
     }
 
 
@@ -646,44 +874,72 @@ public class PlanNewController {
         return RStatus.successList(listMono);
     }
 
+
     /**
      * 计划列表-下拉
      * @param request
-     * @return {@link Mono}<{@link RStatus}<{@link Paged}<{@link PlanNew}>>>
+     * @return {@link Mono}<{@link RStatus}<{@link List}<{@link SelectPlanRes1}>>>
      */
     @PostMapping("planSelect")
-    public Mono<RStatus<List<PlanNew>>> planSelect(@RequestBody PosterTemSelect request)   {
+    public Mono<RStatus<List<SelectPlanRes1>>> planSelect(@RequestBody PosterTemSelect request)   {
         Criteria criteria= Criteria.empty() ; //poster_template_id
         if (Objects.nonNull(request.getName()) && "" != request.getName()) {
             criteria = criteria.and("name").is(request.getName());
         }
-        Mono<List<PlanNew>> listMono = template.select(Query.query(criteria), PlanNew.class).collectList();
-        return RStatus.successList(listMono);
+        Mono<List<SelectPlanRes1>> listMono = template.select(Query.query(criteria), PlanNew.class).flatMap(fm -> {
+            SelectPlanRes1 selectPlanRes1 = new SelectPlanRes1();
+            selectPlanRes1.setName(fm.name());
+            selectPlanRes1.setPlanNewId(fm.planNewId());
+            return Mono.just(selectPlanRes1);
+        }).collectList();
+        Mono<List<SelectPlanRes1>> listMono1 = template.select(Query.query(criteria), ListeningPlanNew.class).flatMap(fm -> {
+            SelectPlanRes1 selectPlanRes2 = new SelectPlanRes1();
+            selectPlanRes2.setName(fm.name());
+            selectPlanRes2.setPlanNewId(fm.listeningPlanNewId());
+            return Mono.just(selectPlanRes2);
+        }).collectList();
+        Mono<List<SelectPlanRes1>> arrayListMono = Mono.zip(listMono, listMono1).flatMap(f -> {
+            List<SelectPlanRes1> t1 = f.getT1();
+            List<SelectPlanRes1> t2 = f.getT2();
+            ArrayList<SelectPlanRes1> objects = new ArrayList<>();
+            objects.addAll(t1);
+            objects.addAll(t2);
+            return Mono.just(objects);
+        });
+        return RStatus.successList(arrayListMono);
     }
 
+
     /**
      * 计划列表
      * @param request
-     * @return {@link Mono}<{@link RStatus}<{@link Paged}<{@link PlanNew}>>>
+     * @return {@link Mono}<{@link RStatus}<{@link Paged}<{@link ListeningPlanNewRes2}>>>
      */
     @PostMapping("planList")
-    public Mono<RStatus<Paged<PlanNewRes>>> page(@RequestBody PlanReqPage request)   {
+    public Mono<RStatus<Paged<ListeningPlanNewRes2>>> page(@RequestBody PlanReqPage request)   {
+        if (2 == request.getType()) {
+          return   listeningPlanService.page(request);
+        }else {
+          return getType1(request);
+        }
+    }
+    private Mono<RStatus<Paged<ListeningPlanNewRes2>>> getType1(PlanReqPage request) {
         Criteria criteria= Criteria.empty() ; //poster_template_id
-        if (Objects.nonNull(request.getCode()) && "" != request.getCode()) {
-            criteria = criteria.and("code").is(request.getCode());
+        if (Objects.nonNull(request.getCode()) && "" != request.getCode().trim()) {
+            criteria = criteria.and("code").like("%"+request.getCode()+"%");
         }
-        if (Objects.nonNull(request.getName()) && "" != request.getName()) {
-            criteria = criteria.and("name").is(request.getName());
+        if (Objects.nonNull(request.getName()) && "" != request.getName().trim()) {
+            criteria = criteria.and("name").like("%"+request.getName()+"%");
         }
-        if (Objects.nonNull(request.getCreateUser()) && "" != request.getCreateUser()) {
-            criteria = criteria.and("create_user").like(request.getCreateUser());
+        if (Objects.nonNull(request.getCreateUser()) && "" != request.getCreateUser().trim()) {
+            criteria = criteria.and("create_user").like("%"+request.getCreateUser()+"%");
         }
         if (Objects.nonNull(request.getPosterTemplateId()) && 0L != request.getPosterTemplateId()) {
             criteria = criteria.and("poster_template_id").is(request.getPosterTemplateId());
         }
-        if (Objects.nonNull(request.getType()) && 0L != request.getType()) {
-            criteria = criteria.and("type").is(request.getType());
-        }
+//        if (Objects.nonNull(request.getType()) && 0L != request.getType()) {
+//            criteria = criteria.and("type").is(request.getType());
+//        }
         Query query = Query.query(criteria);
         Criteria finalCriteria = criteria;
         int skip  = (request.getPage() - 1) * request.getSize();
@@ -693,44 +949,35 @@ public class PlanNewController {
                 .offset(skip)
                 .limit(limit)
                 .sort(Sort.by(Sort.Order.desc("created_at"))), PlanNew.class);
-
-        Flux<Poster> poster_template_id = created_at.flatMap(f -> {
-            Long aLong = f.posterTemplateId();
-            if (Objects.isNull(aLong)) {
-                aLong = 0L;
-            }
-            return template.select(Query.query(Criteria.where("poster_template_id").is(aLong)), Poster.class);
-        });
-        Mono<Paged<PlanNewRes>> pagedMono1 = Mono.zip(count, created_at.collectList(), poster_template_id.collectList()).flatMap(f -> {
-            List<PlanNew> t2 = f.getT2();
-            List<Poster> t3 = f.getT3();
-            List<PlanNewRes> collect = t2.stream().map(fe -> {
-                PlanNewRes planNewRes = new PlanNewRes();
-//                Optional<String> first = t3.stream().filter(ff -> Objects.nonNull( ff.posterTemplateId())
-//                        &&  Objects.nonNull( fe.posterTemplateId())
-//                        &&  ff.posterTemplateId().equals(fe.posterTemplateId()))
-//                        .filter(f11->Objects.nonNull(f11.generateImagesUrl()))
-//                        .map(Poster::generateImagesUrl).findFirst();
-//                first.ifPresent(planNewRes::setPosterUrl);
-                planNewRes.setPlanNew(fe);
-                planNewRes.setPosterUrl(fe.previewUrl());
-                return planNewRes;
-            }).collect(Collectors.toList());
-            Paged<PlanNewRes> planNewResPaged = new Paged<>(f.getT1(), collect, request.getPage(), request.getSize());
+        Mono<List<ListeningPlanNewRes2>> listMono = created_at.flatMap(f -> {
+            Mono<String> poster_template_id = template.selectOne(Query.query(Criteria.where("poster_template_id")
+                    .is(f.posterTemplateId())), PosterTemplate.class).flatMap(f0 -> Mono.just(f0.posterTemplateName()))
+                    .switchIfEmpty(Mono.just("")) //Mono.error(new BaseException("查询海报模版 id:"+f.posterTemplateId()+"=>空"))
+                    .onErrorResume(throwable -> Mono.error(new Exception("查询海报模版 id:" + f.posterTemplateId() + "error:" + throwable.getMessage())));
+            Mono<String> id = template.selectOne(Query.query(Criteria.where("id").is(f.groupId())), GroupType.class)
+                    .flatMap(f1 -> Mono.just(f1.name()))
+                    .switchIfEmpty(Mono.just(""))//Mono.error(new BaseException("查询GroupType id:"+f.groupId()+"=>空"))
+                    .onErrorResume(throwable -> Mono.error(new Exception("查询GroupType id:" + f.groupId() + "error:" + throwable.getMessage())));
+            return Mono.zip(Mono.just(f), poster_template_id, id).flatMap(ff -> {
+                PlanNew t1 = ff.getT1();
+                ListeningPlanNewRes2 listeningPlanNewRes = new ListeningPlanNewRes2();
+                listeningPlanNewRes.setPlanNewId(t1.planNewId());
+                listeningPlanNewRes.setCode(t1.code());
+                listeningPlanNewRes.setName(t1.name());
+                listeningPlanNewRes.setCreatedAt(t1.createdAt());
+                listeningPlanNewRes.setCreateUser(t1.createUser());
+                listeningPlanNewRes.setType(t1.type());
+                listeningPlanNewRes.setGroupName(ff.getT3());
+                listeningPlanNewRes.setPreviewUrl(t1.previewUrl());
+                listeningPlanNewRes.setPosterTemplateName(ff.getT2());
+                return Mono.just(listeningPlanNewRes);
+            });
+        }).collectList();
+        Mono<Paged<ListeningPlanNewRes2>> pagedMono = Mono.zip(count, listMono).flatMap(ff -> {
+            Long t1 = ff.getT1();
+            Paged<ListeningPlanNewRes2> planNewResPaged = new Paged<>(t1, ff.getT2(), request.getPage(), request.getSize());
             return Mono.just(planNewResPaged);
         });
-//        Mono<Paged<PlanNew>> pagedMono = template.count(query, PlanNew.class).flatMap(fm ->
-//                template.select(Query.query(finalCriteria)
-//                        .offset(skip)
-//                        .limit(limit)
-//                        .sort(Sort.by(Sort.Order.desc("created_at"))),PlanNew.class)
-//                        .collectList()
-//                        .map(list -> new Paged<>(fm, list,request.getPage(),request.getSize()))
-//        );
-        return RStatus.successList(pagedMono1);
+        return RStatus.successList(pagedMono);
     }
-
-
-
-
 }

+ 31 - 12
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/PlanNewOutController.java

@@ -33,7 +33,6 @@ import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
 
-
 /**
  * 计划-H5
  * @author lw12420
@@ -171,41 +170,57 @@ public class PlanNewOutController {
                 criteria =criteria.and("size_type").is(1);
             }
             Query query = Query.query(criteria);
-            Mono<List<Image>> image = template.select(query, Image.class).onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()+"7")))
+            Mono<List<Image>> image = template.select(query, Image.class)
+                    .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()+"7")))
                     .collectList();
             Mono<List<Material>> text = template.select(Query.query(Criteria.where("type")
-                    .is(4).and("deleted_at").isNull().and("group_type_id").is(group_type_id)), Material.class).onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()+"8")))
+                    .is(4).and("deleted_at").isNull().and("group_type_id").is(group_type_id)), Material.class)
+                    .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()+"8")))
                     .collectList();
-
             Mono<UserVisits> wx_user_id ;
             if (Objects.isNull(request.getWx_user_id()) || "".equals(request.getWx_user_id())) {
                 wx_user_id=Mono.just(new UserVisits(null,null,null));
             }else{
                 Mono<UserVisits> insert = template.insert(new UserVisits(null, request.getWx_user_id(), 1));
-                 wx_user_id = template.selectOne(Query.query(Criteria.where("wx_user_id").is(request.getWx_user_id())), UserVisits.class).onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()+"9")))
+                 wx_user_id = template.selectOne(Query.query(Criteria.where("wx_user_id").is(request.getWx_user_id())), UserVisits.class)
+                         .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()+"9")))
                         .flatMap(f -> {
                             if (f.num() >= 4) {
                                 return Mono.just(f);
                             } else {
-                                return template.update(new UserVisits(f.id(), f.wxUserId(), f.num() + 1)).onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()+"10")));
+                                return template.update(new UserVisits(f.id(), f.wxUserId(), f.num() + 1))
+                                        .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()+"10")));
                             }
                         }).switchIfEmpty(insert);
             }
-
             Mono<List<H5ImageAndText>> arrayListMono = Mono.zip(code, domain, image, text).flatMap(f -> {
                 //H5ImageAndText
                 Integer integer = f.getT1().pageShow();//群数量
                 List<Domain> t2 = f.getT2();
+                //【ID1015656】
+                //计划2.0H5页面中的群封面、标题不重复
                 List<Image> t3 = f.getT3();
+                if(t3.size()<integer){
+                    throw new BaseException("群封面数小于计划中设置的群数量");
+                }
                 List<Material> t4 = f.getT4();
+                if(t4.size()<integer){
+                    throw new BaseException("群名称数小于计划中设置的群数量");
+                }
+                ArrayList<Long> listImg = new ArrayList<>();
+                ArrayList<Long> listTxt = new ArrayList<>();
                 List<H5ImageAndText> h5ImageAndTexts = new ArrayList<>();
                 IntStream.range(0, integer).forEach(i -> {
                     H5ImageAndText h5ImageAndText = new H5ImageAndText();
-                    Image image1 = t3.get(RandomUtil.randomInt(0,t3.size()));
+                    List<Image> collect = t3.stream().filter(fff -> !listImg.contains(fff.id())).collect(Collectors.toList());
+                    Image image1 = collect.get(RandomUtil.randomInt(0,collect.size()));
+                    listImg.add(image1.id());
                     h5ImageAndText.setImage(image1.image());
                     Domain domain1 = t2.get(RandomUtil.randomInt(0,t2.size()));
                     h5ImageAndText.setDomain(domain1.domain());
-                    Material material = t4.get(RandomUtil.randomInt(0,t4.size()));
+                    List<Material> collect1 = t4.stream().filter(fff -> !listTxt.contains(fff.id())).collect(Collectors.toList());
+                    Material material = collect1.get(RandomUtil.randomInt(0,collect1.size()));
+                    listTxt.add(material.id());
                     h5ImageAndText.setName(material.content());
                     h5ImageAndText.setRemark(material.remark());
                     h5ImageAndTexts.add(h5ImageAndText);
@@ -289,7 +304,8 @@ public class PlanNewOutController {
             map.put(request.getUnique(),0);
             request.setUserVisits(0);
         }
-        Mono<PlanNew> code0 = template.selectOne(Query.query(Criteria.where("code").is(request.getCode())), PlanNew.class).switchIfEmpty(Mono.error(new BaseException(" code错误")))
+        Mono<PlanNew> code0 = template.selectOne(Query.query(Criteria.where("code").is(request.getCode())), PlanNew.class)
+                .switchIfEmpty(Mono.error(new BaseException(" code错误")))
                 .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage())));
         Mono<DataLists0> dataLists0Mono =  code0.flatMap(ftmp->{
             //(如果wx_user_id值不为空则使用清水分类)
@@ -318,7 +334,9 @@ public class PlanNewOutController {
                 Map<Integer, List<PlanNewBackgroupPoster>> collect = f.getT4().stream().collect(Collectors.groupingBy(PlanNewBackgroupPoster::qsOrFx));
                 //营销-清水
                 if (Objects.nonNull(request.getWx_user_id()) && !"".equals(request.getWx_user_id())) {
-                    List<PlanNewBackgroupPoster> qs = collect.get(2).stream().sorted(Comparator.comparing(PlanNewBackgroupPoster::index)).collect(Collectors.toList());
+                    List<PlanNewBackgroupPoster> qs = collect.get(2).stream()
+                            .sorted(Comparator.comparing(PlanNewBackgroupPoster::index))
+                            .collect(Collectors.toList());
                     if(Objects.nonNull(qs) && !qs.isEmpty()){
                         if (qs.size() <= request.getUserVisits()) {
                             Integer userVisits = request.getUserVisits();
@@ -339,7 +357,8 @@ public class PlanNewOutController {
                         dataLists0.setLimitTimeRemark(qsSetting.limitTimeRemark());
                     }
                 }else {
-                    List<PlanNewBackgroupPoster> fx = collect.get(1).stream().sorted(Comparator.comparing(PlanNewBackgroupPoster::index)).collect(Collectors.toList());
+                    List<PlanNewBackgroupPoster> fx = collect.get(1).stream()
+                            .sorted(Comparator.comparing(PlanNewBackgroupPoster::index)).collect(Collectors.toList());
                     if (Objects.nonNull(fx) &&fx.size() != 0) {
                         if (fx.size() <= request.getUserVisits()) {
                             Integer userVisits = request.getUserVisits();

+ 2 - 2
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PlanReq.java

@@ -8,7 +8,7 @@ import java.util.List;
 @Data
 public class PlanReq {
 
-    private Long planNewId;
+    private String planNewId;
     /**
      * 计划名
      */
@@ -16,7 +16,7 @@ public class PlanReq {
 //    private String createUser;
 //    private String createId;
     /**
-     * // 1加群裂变2短剧裂变3会话裂变4红包裂变5小说裂变
+     * // 1.加群计划 2.听书计划
      */
     private  Integer type;
     /**

+ 1 - 1
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PlanReqPage.java

@@ -11,7 +11,7 @@ public class PlanReqPage {
 
     private String name; //计划名
     private String createUser;
-    private  Integer type;// 1加群裂变2短剧裂变3会话裂变4红包裂变5小说裂变
+    private  Integer type;// 1加群裂变2听书计划
     private  String code;
     private  Long posterTemplateId;//海报id
 

+ 48 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/PlanNewAllRs.java

@@ -0,0 +1,48 @@
+package com.webflux.launchadmin.mysql.controller.planNew.res;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.time.ZonedDateTime;
+@Data
+@AllArgsConstructor
+public class PlanNewAllRs {
+
+  private   String planNewId;
+    private   String name; //计划名
+    private   String createUser;
+    private   String createId;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private    ZonedDateTime createdAt;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private  ZonedDateTime updatedAt;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private   ZonedDateTime deletedAt;
+    private   Integer type;// 1加群裂变2短剧裂变3会话裂变4红包裂变5小说裂变
+    private   String code;
+    private   Long  groupId; //分类id
+    private   Long posterTemplateId;//海报id
+    private  Integer pageShow;//群数量
+    private  Integer pageLine;//单行数量
+    private   Integer count;//清水分类/展示次数
+    private  Long listAudioId;//	列表音频id
+    private   Long retAudioId;//返回音频id
+    private  String link;//入群链接
+    private  Integer  isAddQun;//加群确认页开关
+    private  Long backgroundGroupId;//背景组id
+    private   Long homePageId;//首页模版id
+    private  Integer topAdvNum;//顶部广告 -1 false  其他true
+    private  Integer bottomAdvNum;//	底部广告 -1 false  其他true
+    private   Long returnLoopId;//	返回广告 -1 false  其他true
+    private  Long backgroundGroupQsId;//清水背景组id
+    private  Integer topAdvBl;
+    private  Integer bottomAdvBl;
+    private   Integer returnLoopBl;
+    private   Long groupIdQs;
+    private  String baiduDot;
+    private  Long backgroundGroupIdNewAdd; //background_groupId_new_add
+    private  String previewUrl;
+    private  Integer redirectType; // 1三方链接 2计划链接
+    private  Long redirectPlanId;
+}

+ 39 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/PlanNewBackgroupPosterAllRes.java

@@ -0,0 +1,39 @@
+package com.webflux.launchadmin.mysql.controller.planNew.res;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.relational.core.mapping.Column;
+
+import java.time.ZonedDateTime;
+@Data
+@AllArgsConstructor
+public class PlanNewBackgroupPosterAllRes {
+
+  private Long id;//
+    private   Long audioId;//音频id
+    private   Long groupId;//客服组id
+    private   String image;//背景组图片
+    private   String kefu;
+    private   String limitTime;//分享限时
+    private  String limitTimeRemark;//	分享限时内提示
+    private   Integer status;//0:h5链接 1:客服二维码
+    @Column("idx")
+    private   Integer index;//	背景图序号
+    private  String serviceGroupId;//客服组 ,分割
+    private   Integer serviceGroupType ;//1:客服组 2:上传图片
+    private   Integer qsOrFx;//1:分享背景组 2:清水背景组
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private  ZonedDateTime createdAt;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private  ZonedDateTime updatedAt;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private  ZonedDateTime deletedAt;
+    private   String planNewId;
+    private   String generateImagesJson;
+    /**
+     * 生成图片
+     */
+    private   String generateImagesUrl;
+}

+ 8 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/SelectPlanRes.java

@@ -0,0 +1,8 @@
+package com.webflux.launchadmin.mysql.controller.planNew.res;
+
+import lombok.Data;
+
+@Data
+public class SelectPlanRes {
+    private String name; //计划名
+}

+ 8 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/SelectPlanRes1.java

@@ -0,0 +1,8 @@
+package com.webflux.launchadmin.mysql.controller.planNew.res;
+
+import lombok.Data;
+
+@Data
+public class SelectPlanRes1 extends SelectPlanRes{
+    private String planNewId; //计划名
+}

+ 8 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/SelectPlanRes2.java

@@ -0,0 +1,8 @@
+package com.webflux.launchadmin.mysql.controller.planNew.res;
+
+import lombok.Data;
+
+@Data
+public class SelectPlanRes2 extends SelectPlanRes {
+    private String planNewId; //计划名
+}

+ 22 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/entity/listening/ListeningAudio.java

@@ -0,0 +1,22 @@
+package com.webflux.launchadmin.mysql.entity.listening;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.relational.core.mapping.Table;
+
+import java.time.ZonedDateTime;
+
+@Table("listening_audio")
+public record ListeningAudio(@Id Long newAudioId,
+                             String audioName,//节点
+                             String audioImageUrl,//封面图片
+                             String audioUrl, //音频链接
+                             Integer popupNode, //弹窗节点
+                             Integer idxNum,//排序
+                             String createUser,
+                             String createId,
+                             @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") ZonedDateTime createdAt,
+                             @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") ZonedDateTime updatedAt,
+                             @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") ZonedDateTime deletedAt
+                               ) {
+}

+ 32 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/entity/listening/ListeningPlanNew.java

@@ -0,0 +1,32 @@
+package com.webflux.launchadmin.mysql.entity.listening;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.relational.core.mapping.Table;
+
+import java.time.ZonedDateTime;
+
+@Table("listening_plan_new")
+public record ListeningPlanNew(
+        @Id
+        String listeningPlanNewId,
+        String name, //计划名
+        String createUser,
+        String createId,
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") ZonedDateTime createdAt,
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") ZonedDateTime updatedAt,
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") ZonedDateTime deletedAt,
+        Integer type,// 值:听书裂变
+        String code,
+        Long  groupId, //营销分类id
+        String groupName,//营销分类name
+        Long posterTemplateId,//海报id
+        Integer pageShow,//群数量
+        Integer pageLine,//单行数量
+        String link,//入群链接
+        Long backgroundGroupId,//营销背景组id
+        String baiduDot,
+       String previewUrl //预览url
+
+) {
+}

+ 36 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/entity/listening/ListeningPlanNewBackgroupPoster.java

@@ -0,0 +1,36 @@
+package com.webflux.launchadmin.mysql.entity.listening;
+
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.relational.core.mapping.Column;
+import org.springframework.data.relational.core.mapping.Table;
+
+import java.time.ZonedDateTime;
+
+@Table("listening_plan_new_backgroup_poster")
+public record ListeningPlanNewBackgroupPoster(@Id Long id,//
+                                              Long audioId,//音频id
+                                              Long groupId,//客服组id
+                                              String image,//背景组图片
+                                              String kefu,
+                                              String limitTime,//分享限时
+                                              String limitTimeRemark,//	分享限时内提示
+                                              Integer status,//0:h5链接 1:客服二维码
+                                              @Column("idx")
+                                              Integer index,//	背景图序号
+                                              String serviceGroupId,//客服组 ,分割
+                                              Integer serviceGroupType ,//1:客服组 2:上传图片
+                                              Integer qsOrFx,//1:分享背景组 2:清水背景组
+                                              @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") ZonedDateTime createdAt,
+                                              @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") ZonedDateTime updatedAt,
+                                              @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") ZonedDateTime deletedAt,
+                                              String listeningPlanNewId,
+                                              String generateImagesJson,
+                                              /**
+                                               * 生成图片
+                                               */
+                                              String generateImagesUrl
+
+){
+}

+ 3 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/entity/planNew/Material.java

@@ -23,4 +23,7 @@ public record Material(@Id Long id,
                        Integer groupTypeId,
                        String remark
                        ) {
+    public static Material getMaterial(){
+        return new Material(null,null,null,null,null,null,null,null,null,null,null);
+    }
 }

+ 1 - 1
launch-admin/src/main/java/com/webflux/launchadmin/mysql/entity/planNew/PlanNew.java

@@ -10,7 +10,7 @@ import java.time.ZonedDateTime;
 @Table("plan_new")
 public record PlanNew(
         @Id
-        Long planNewId,
+        String planNewId,
         String name, //计划名
         String createUser,
         String createId,

+ 1 - 1
launch-admin/src/main/java/com/webflux/launchadmin/mysql/entity/planNew/PlanNewBackgroupPoster.java

@@ -25,7 +25,7 @@ public record PlanNewBackgroupPoster(@Id Long id,//
                                      @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") ZonedDateTime createdAt,
                                      @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") ZonedDateTime updatedAt,
                                      @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") ZonedDateTime deletedAt,
-                                     Long planNewId,
+                                     String planNewId,
                                      String generateImagesJson,
                                      /**
                                       * 生成图片

+ 1066 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/service/listening/ListeningPlanServiceImpl.java

@@ -0,0 +1,1066 @@
+package com.webflux.launchadmin.mysql.service.listening;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.webflux.launchadmin.config.BaseContextHandler;
+import com.webflux.launchadmin.global.BaseException;
+import com.webflux.launchadmin.mysql.controller.listening.req.*;
+import com.webflux.launchadmin.mysql.controller.listening.res.DataListsShare;
+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.PlanReq;
+import com.webflux.launchadmin.mysql.controller.planNew.req.PlanReqPage;
+import com.webflux.launchadmin.mysql.controller.planNew.req.ServiceGroupSettingItemRequest;
+import com.webflux.launchadmin.mysql.entity.listening.ListeningAudio;
+import com.webflux.launchadmin.mysql.entity.listening.ListeningPlanNew;
+import com.webflux.launchadmin.mysql.entity.listening.ListeningPlanNewBackgroupPoster;
+import com.webflux.launchadmin.mysql.entity.planNew.*;
+import com.webflux.launchadmin.mysql.service.planNew.structure.GoRequest;
+import com.webflux.launchadmin.mysql.service.planNew.structure.Item;
+import com.webflux.launchcommon.returnObj.Paged;
+import com.webflux.launchcommon.returnObj.RStatus;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
+import org.springframework.data.relational.core.query.Criteria;
+import org.springframework.data.relational.core.query.Query;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+import org.springframework.web.bind.annotation.RequestParam;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.time.ZonedDateTime;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+@Slf4j
+@Service
+public class ListeningPlanServiceImpl implements ListeningPlanServiceInterface{
+    @Value("${go.data.createImage}")
+    private String value;
+
+    @Resource
+    private R2dbcEntityTemplate template;
+    @Override
+    public Mono<RStatus<Paged<ListeningPlanNewRes2>>> page(PlanReqPage request) {
+        Criteria criteria= Criteria.empty() ; //poster_template_id
+        if (Objects.nonNull(request.getCode()) && "" != request.getCode().trim()) {
+            criteria = criteria.and("code").like("%"+request.getCode()+"%");
+        }
+        if (Objects.nonNull(request.getName()) && "" != request.getName().trim()) {
+            criteria = criteria.and("name").like("%"+request.getName()+"%");
+        }
+        if (Objects.nonNull(request.getCreateUser()) && "" != request.getCreateUser().trim()) {
+            criteria = criteria.and("create_user").like("%"+request.getCreateUser()+"%");
+        }
+        if (Objects.nonNull(request.getPosterTemplateId()) && 0L != request.getPosterTemplateId()) {
+            criteria = criteria.and("poster_template_id").is(request.getPosterTemplateId());
+        }
+//        if (Objects.nonNull(request.getType()) && 0 != request.getType()) {
+//            criteria = criteria.and("type").is(request.getType());
+//        }
+        Query query = Query.query(criteria);
+        Criteria finalCriteria = criteria;
+        int skip  = (request.getPage() - 1) * request.getSize();
+        int limit = request.getPage() * request.getSize();
+        return RStatus.successList(Mono.zip(template.count(query, ListeningPlanNew.class), template.select(Query.query(finalCriteria)
+                .offset(skip)
+                .limit(limit)
+                .sort(Sort.by(Sort.Order.desc("created_at"))), ListeningPlanNew.class).flatMap(f -> {
+            Mono<String> poster_template_id = template.selectOne(Query.query(Criteria.where("poster_template_id")
+                    .is(f.posterTemplateId())), PosterTemplate.class).flatMap(f0 -> Mono.just(f0.posterTemplateName()))
+                    .switchIfEmpty(Mono.just("")) //Mono.error(new BaseException("查询海报模版 id:"+f.posterTemplateId()+"=>空"))
+                    .onErrorResume(throwable -> Mono.error(new Exception("查询海报模版 id:" + f.posterTemplateId() + "error:" + throwable.getMessage())));
+            Mono<String> id = template.selectOne(Query.query(Criteria.where("id").is(f.groupId())), GroupType.class)
+                    .flatMap(f1 -> Mono.just(f1.name()))
+                    .switchIfEmpty(Mono.just(""))//Mono.error(new BaseException("查询GroupType id:"+f.groupId()+"=>空"))
+                    .onErrorResume(throwable -> Mono.error(new Exception("查询GroupType id:" + f.groupId() + "error:" + throwable.getMessage())));
+            return Mono.zip(Mono.just(f), poster_template_id, id).flatMap(ff -> {
+                ListeningPlanNew t1 = ff.getT1();
+                ListeningPlanNewRes2 listeningPlanNewRes = new ListeningPlanNewRes2();
+                listeningPlanNewRes.setPlanNewId(t1.listeningPlanNewId());
+                listeningPlanNewRes.setCode(t1.code());
+                listeningPlanNewRes.setName(t1.name());
+                listeningPlanNewRes.setCreatedAt(t1.createdAt());
+                listeningPlanNewRes.setCreateUser(t1.createUser());
+                listeningPlanNewRes.setType(t1.type());
+                listeningPlanNewRes.setGroupName(ff.getT3());
+                listeningPlanNewRes.setPreviewUrl(t1.previewUrl());
+                listeningPlanNewRes.setPosterTemplateName(ff.getT2());
+                return Mono.just(listeningPlanNewRes);
+            });
+        }).collectList()).flatMap(ff -> {
+            Long t1 = ff.getT1();
+            Paged<ListeningPlanNewRes2> planNewResPaged = new Paged<>(t1, ff.getT2(), request.getPage(), request.getSize());
+            return Mono.just(planNewResPaged);
+        }));
+    }
+    @Override
+    public Mono<RStatus<List<GroupType>>> groupTypeSlt (String name){
+        Criteria criteria= Criteria.where("group_type").is(1);
+        if (Objects.nonNull(name) && "" != name) {
+            criteria = criteria.and("name").like("%"+name+"%");
+        }
+        Mono<List<GroupType>> listMono = template.select(Query.query(criteria), GroupType.class).collectList();
+        return RStatus.success(listMono);
+    }
+    @Override
+    public Mono<RStatus<String>> savePlan(PlanReq saveRequest) {
+        String userName = BaseContextHandler.getUserName();
+        String userId = BaseContextHandler.getUserId();
+        boolean bl=Objects.nonNull(saveRequest.getPlanNewId()) || "".equals(saveRequest.getPlanNewId().trim());
+        saveRequest.setCode(IdUtil.fastSimpleUUID());
+        Long posterTemplateId = saveRequest.getPosterTemplateId();
+        //预览Url
+         Mono<String> stringMono1 = template
+                .select(Query.query(Criteria.where("poster_template_id")
+                        .is(posterTemplateId)).sort(Sort.by(Sort.Order.asc("created_at"))), Poster.class)
+                .collectList().flatMap(f -> {
+                    Poster poster = f.get(0);
+                    String posterTemplate = poster.posterTemplate();
+                    JSONObject jsonObject = JSONUtil.parseObj(posterTemplate);
+                    GoRequest goRequest = new GoRequest();
+                    BeanUtil.copyProperties(jsonObject, goRequest);
+                    ServiceGroupSettingItemRequest serviceGroupSettingItemRequest = saveRequest.getBackgroupFxSetting().get(0);
+                    System.out.println(goRequest);
+                    Mono<String> stringMono = saveAndUpdatePlanGenerateImage0(goRequest,
+                            setCusqrcodeRtUrl(goRequest),
+                            serviceGroupSettingItemRequest,
+                            saveRequest);
+                    return stringMono;
+                });
+        Mono<StringBuilder> link=Mono.just(new StringBuilder(saveRequest.getLink()));
+        Mono<ListeningPlanNew> insert = Mono.zip(stringMono1, link).flatMap(f->{
+
+            ListeningPlanNew plan = new ListeningPlanNew(
+                    bl  ?IdUtil.fastSimpleUUID():saveRequest.getPlanNewId(),
+                    saveRequest.getName(),
+                    userName,
+                    userId,
+                    ZonedDateTime.now(),
+                    ZonedDateTime.now(),
+                    null,
+                    saveRequest.getType(),
+                    saveRequest.getCode(),
+                    saveRequest.getGroupId(),
+                    null,
+                    saveRequest.getPosterTemplateId(),
+                    saveRequest.getPageShow(),
+                    saveRequest.getPageLine(),
+                    f.getT2().toString(),
+                    saveRequest.getBackgroundGroupId(),
+                    saveRequest.getBaiduDot(),
+                    f.getT1()
+            );
+            return !bl? template.update(plan) : template.insert(plan);
+        });
+        Mono<String> map = insert.flatMap(f -> {
+            List<ServiceGroupSettingItemRequest> backgroupFxSetting = saveRequest.getBackgroupFxSetting();
+            //Flux<ListeningPlanNewBackgroupPoster> just = Flux.just();
+            ArrayList<ListeningPlanNewBackgroupPoster> listeningPlanNewBackgroupPosters = new ArrayList<>();
+            backgroupFxSetting.forEach(fx -> {
+                ListeningPlanNewBackgroupPoster listeningPlanNewBackgroupPoster = fxBackgroupSettingsSave(fx, f.listeningPlanNewId(), 1);
+                listeningPlanNewBackgroupPosters.add(listeningPlanNewBackgroupPoster);
+               // just.concatWith(Flux.just(listeningPlanNewBackgroupPoster));
+            });
+            Flux<ListeningPlanNewBackgroupPoster> just = Flux.fromIterable(listeningPlanNewBackgroupPosters);
+            Mono<Long>  ml;
+                    if(!bl){
+                        ml= template.delete(Query.query(Criteria.where("plan_new_id").is(f.listeningPlanNewId())),ListeningPlanNewBackgroupPoster.class);
+                    }else {
+                        ml=Mono.just(1l);
+                    }
+
+            return  Mono.zip(batchInsert(just), Mono.just(f),ml).flatMap(ff -> {
+                ListeningPlanNew t2 = ff.getT2();
+                return Mono.just(t2.listeningPlanNewId());
+            });
+        });
+        return  RStatus.success(map);
+    }
+
+
+    public Mono<List<ListeningPlanNewBackgroupPoster>> batchInsert(Flux<ListeningPlanNewBackgroupPoster> entities) {
+        Mono<List<ListeningPlanNewBackgroupPoster>> listMono = entities.flatMap(entity -> template.insert(ListeningPlanNewBackgroupPoster.class).using(entity)).collectList();
+        return listMono;
+    }
+    public ListeningPlanNewBackgroupPoster fxBackgroupSettingsSave( ServiceGroupSettingItemRequest request,String planNewId,Integer qsOrFx){
+        return new ListeningPlanNewBackgroupPoster(null,
+                request.getAudioId(),
+                request.getGroupId(),
+                request.getImage(),
+                request.getKefu(),
+                request.getLimitTime(),
+                request.getLimitTimeRemark(),
+                request.getStatus(),
+                request.getIndex(),
+                request.getServiceGroupId(),
+                request.getServiceGroupType(),
+                qsOrFx,
+                ZonedDateTime.now(),
+                null,
+                null,
+                planNewId,
+                null,
+                null);
+
+    }
+
+    public Mono<List<StringBuilder>> setCusqrcodeRtUrl(GoRequest goRequest) {
+        List<Item> collect = goRequest.getItem().stream()
+                .filter(f -> "cusqrcode".equals(f.getT())
+                        && Objects.nonNull(f.getPlanId())
+                        && f.getIsRandom()).collect(Collectors.toList());
+        Mono<List<StringBuilder>> stringBuilderMono =null;
+        if (Objects.nonNull(collect) && !collect.isEmpty()) {
+            List<Long> collect1 = collect.stream().map(Item::getPlanId).collect(Collectors.toList());
+            stringBuilderMono = template.select(Query.query(Criteria.where("listening_plan_new_id").in(collect1)), ListeningPlanNew.class)
+                    .flatMap(f -> Mono.zip(Mono.just(f), template.select(Query.query(Criteria.where("group_type_id").is(f.groupId())
+                                    .and("status").is(1).and("type").is(1).and("deleted_at").isNull()), DomainSelect.class)
+                                    .collectList()
+                                    .switchIfEmpty(Mono.just(List.of())), (a, b) -> {
+                                StringBuilder stringBuilder = new StringBuilder();
+                                if (Objects.nonNull(b) && !b.isEmpty()) {
+                                    DomainSelect domainSelect = b.get(RandomUtil.randomInt(0, b.size()));
+                                    stringBuilder.append("http://");
+                                    stringBuilder.append( get6Str());
+                                    stringBuilder.append(".");
+                                    stringBuilder.append(domainSelect.domain());
+                                    stringBuilder.append("/index.html?code=");
+                                    stringBuilder.append(a.code());
+                                    stringBuilder.append("&sk=");
+                                    stringBuilder.append(IdUtil.fastSimpleUUID());
+                                }else {
+                                    throw new BaseException("通过计划id:"+a.listeningPlanNewId() +"的营销类型查询域名为空");
+                                }
+                                Optional<Item> first = collect.stream()
+                                        .filter(ft -> ft.getPlanId()
+                                                .equals(f.listeningPlanNewId()) && (Objects.isNull(ft.getV()) || "".equals(ft.getV()))).findFirst();
+                                first.ifPresent(item -> item.setV(stringBuilder.toString()));
+                                return stringBuilder;
+                            })
+                    ).collectList();
+        }
+        if (Objects.isNull(stringBuilderMono)) {
+            return Mono.just(List.of());
+        }
+        return stringBuilderMono;
+    }
+
+    @Override
+    public Mono<RStatus<ListeningAudio>> saveOrUpdateAudio(ListeningAudioReq saveRequest) {
+        String userName = BaseContextHandler.getUserName();
+        String userId = BaseContextHandler.getUserId();
+        ListeningAudio listeningAudio = new ListeningAudio(
+                saveRequest.getNewAudioId(),
+                saveRequest.getAudioName(),
+                saveRequest.getAudioImageUrl(),
+                saveRequest.getAudioUrl(),
+                saveRequest.getPopupNode(),
+                saveRequest.getIdxNum(),
+                userName,
+                userId,
+                ZonedDateTime.now(),
+                ZonedDateTime.now(),
+                null
+        );
+        Mono<ListeningAudio> updateOrinsert;
+        if (Objects.nonNull(saveRequest.getNewAudioId())) {
+           updateOrinsert = template.update(listeningAudio);
+        } else {
+           updateOrinsert = template.insert(listeningAudio);
+        }
+        return RStatus.success(updateOrinsert);
+    }
+
+    @Override
+    public Mono<RStatus<Paged<ListeningAudioRes>>> audioList(ListeningAudioReqPage request) {
+        Criteria criteria= Criteria.empty() ; //poster_template_id
+        if (Objects.nonNull(request.getName()) && "" != request.getName().trim()) {
+            criteria = criteria.and("audio_name").like("%"+request.getName()+"%");
+        }
+        Query query = Query.query(criteria);
+        Criteria finalCriteria = criteria;
+        int skip  = (request.getPage() - 1) * request.getSize();
+        int limit = request.getPage() * request.getSize();
+        return RStatus.successList(Mono.zip(template.count(query, ListeningAudio.class),
+                template.select(Query.query(finalCriteria)
+                        .offset(skip)
+                        .limit(limit)
+                        .sort(Sort.by(Sort.Order.asc("idx_num"))), ListeningAudio.class).collectList()).flatMap(f -> {
+            Long t1 = f.getT1();
+            List<ListeningAudio> t2 = f.getT2();
+            List<ListeningAudioRes> collect = t2.stream().map(fm -> {
+                ListeningAudioRes listeningAudioRes = new ListeningAudioRes();
+                listeningAudioRes.setAudioUrl(fm.audioUrl());
+                listeningAudioRes.setAudioImageUrl(fm.audioImageUrl());
+                listeningAudioRes.setAudioName(fm.audioName());
+                listeningAudioRes.setNewAudioId(fm.newAudioId());
+                listeningAudioRes.setCreatedAt(fm.createdAt());
+                listeningAudioRes.setCreateUser(fm.createUser());
+                listeningAudioRes.setIdxNum(fm.idxNum());
+                listeningAudioRes.setPopupNode(fm.popupNode());
+                return listeningAudioRes;
+            }).collect(Collectors.toList());
+            Paged<ListeningAudioRes> planNewResPaged = new Paged<>(t1, collect, request.getPage(), request.getSize());
+            return Mono.just(planNewResPaged);
+        }));
+    }
+
+    @Override
+    public Mono<RStatus<String>> copyById(String listeningPlanNewId) {
+        String userName = BaseContextHandler.getUserName();
+        String userId = BaseContextHandler.getUserId();
+        Mono<ListeningPlanNew> listening_plan_new_id = template
+                .selectOne(Query.query(Criteria.where("listening_plan_new_id").is(listeningPlanNewId)), ListeningPlanNew.class)
+                .switchIfEmpty(Mono.error(new BaseException("计划错误")))
+                .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage())))
+                .flatMap(f -> {
+                    ListeningPlanNew listeningPlanNew = new ListeningPlanNew(null,
+                            f.name(),
+                            userName,
+                            userId,
+                            ZonedDateTime.now(),
+                            ZonedDateTime.now(),
+                            null,
+                            f.type(),
+                            f.code(),
+                            f.groupId(),
+                            f.groupName(),
+                            f.posterTemplateId(),
+                            f.pageShow(),
+                            f.pageLine(),
+                            f.link(),
+                            f.backgroundGroupId(),
+                            f.baiduDot(),
+                            f.previewUrl()
+                    );
+                    return Mono.just(listeningPlanNew);
+                }).flatMap(f -> template.insert(f));
+        Mono<List<ListeningPlanNewBackgroupPoster>> listening_plan_new_id1 =
+                template.select(Query.query(Criteria.where("listening_plan_new_id")
+                        .is(listeningPlanNewId)), ListeningPlanNewBackgroupPoster.class)
+                        .collectList();
+        Mono<String> stringMono = Mono.zip(listening_plan_new_id, listening_plan_new_id1).flatMap(f -> {
+            ListeningPlanNew t1 = f.getT1();
+            List<ListeningPlanNewBackgroupPoster> t2 = f.getT2();
+            if (!t2.isEmpty()) {
+                List<ListeningPlanNewBackgroupPoster> collect = t2.stream().map(request -> new ListeningPlanNewBackgroupPoster(null,
+                        request.audioId(),
+                        request.groupId(),
+                        request.image(),
+                        request.kefu(),
+                        request.limitTime(),
+                        request.limitTimeRemark(),
+                        request.status(),
+                        request.index(),
+                        request.serviceGroupId(),
+                        request.serviceGroupType(),
+                        request.qsOrFx(),
+                        ZonedDateTime.now(),
+                        null,
+                        null,
+                        t1.listeningPlanNewId(),
+                        request.generateImagesJson(),
+                        request.generateImagesUrl())).collect(Collectors.toList());
+                Mono<List<ListeningPlanNewBackgroupPoster>> listMono =
+                        Flux.fromIterable(collect).flatMap(entity -> template.insert(entity)).collectList();
+                return Mono.zip(Mono.just(t1), listMono).flatMap(ff -> {
+                    ListeningPlanNew t11 = ff.getT1();
+                    return Mono.just(t11.listeningPlanNewId());
+                });
+            } else {
+                return Mono.just(t1.listeningPlanNewId());
+            }
+        });
+        return RStatus.success(stringMono);
+
+    }
+
+    @Override
+    public Mono<RStatus<ListeningDataLists>> LandingPageList(OutListeningRequest outListeningRequest) {
+        Mono<ListeningPlanNew> code1 = template.selectOne(Query.query(Criteria.where("code")
+                .is(outListeningRequest.getCode())), ListeningPlanNew.class)
+                .switchIfEmpty(Mono.error(new BaseException(" code错误")))
+                .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage())));
+        Mono<ListeningDataLists> idx_num1 = code1.flatMap(f -> {
+            Mono<List<ListeningAudio>> idx_num = template.select(Query.query(Criteria.empty())
+                    .sort(Sort.by(Sort.Order.asc("idx_num")))
+                    .limit(f.pageShow()), ListeningAudio.class).collectList();
+            return Mono.zip(Mono.just(f), idx_num).flatMap(ff -> {
+                ListeningDataLists listeningDataLists = new ListeningDataLists();
+                ListeningPlanNew t1 = ff.getT1();
+                List<ListeningAudio> t2 = ff.getT2();
+                if (t2.size() < t1.pageShow()) {
+                    throw new BaseException("听书音频小于计划设置数");
+                }
+                List<H5ImageAndTextListening> collect = t2.stream().map(f1 -> {
+                    H5ImageAndTextListening h5ImageAndTextListening = new H5ImageAndTextListening();
+                    h5ImageAndTextListening.setAudioImageUrl(f1.audioImageUrl());
+                    h5ImageAndTextListening.setAudioName(f1.audioName());
+                    h5ImageAndTextListening.setAudioUrl(f1.audioUrl());
+                    h5ImageAndTextListening.setIdxNum(f1.idxNum());
+                    h5ImageAndTextListening.setPopupNode(f1.popupNode());
+                    return h5ImageAndTextListening;
+                }).collect(Collectors.toList());
+                listeningDataLists.setPlanNew(t1);
+                listeningDataLists.setImages(collect);
+                listeningDataLists.setPageLine(t1.pageLine());
+                listeningDataLists.setPageShow(t1.pageShow());
+                return Mono.just(listeningDataLists);
+            });
+        });
+        return RStatus.success(idx_num1);
+    }
+    private static final ConcurrentHashMap<String,Integer> map = new ConcurrentHashMap<>();
+    //清空用户Map数据
+    @Scheduled(cron="1 2 4 * * ?")
+    public void clearUserContextMap(){
+        log.info("清空听书裂变计划-H5用户Map数据》》》》》》》》》》》》》》》》》》》》》》开始");
+        map.clear();
+        log.info("空听书裂变计划-H5用户Map数据》》》》》》》》》》》》》》》》》》》》》》 结束");
+    }
+    @Override
+    public Mono<RStatus<DataListsShare>> share(OutListeningShareRequest request) {
+        if(map.containsKey(request.getUnique())){
+            Integer integer = map.get(request.getUnique());
+            map.put(request.getUnique(),integer+1);
+            request.setUserVisits(integer+1);
+        }else {
+            map.put(request.getUnique(),0);
+            request.setUserVisits(0);
+        }
+        Mono<ListeningPlanNew> code1 = template.selectOne(Query.query(Criteria.where("code")
+                .is(request.getCode())), ListeningPlanNew.class)
+                .switchIfEmpty(Mono.error(new BaseException("hello!!! code错误")))
+                .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage())));
+        Mono<DataListsShare> dataListsShareMono = code1.flatMap(ftmp -> {
+            Mono<ListeningPlanNew> code = Mono.just(ftmp);
+            return Mono.zip(code, getPoster_template_id(code), getPoster(code), getPlanNewBackgroupPoster(code), getQrcode(code)).flatMap(f -> {
+                DataListsShare dataListsShare = new DataListsShare();
+                //按照访问次数设置海报
+                List<Poster> t3 = f.getT3();
+                if (t3.size() != 0) {
+                    if (t3.size() <= request.getUserVisits()) {
+                        dataListsShare.setPoster(t3.getLast());
+                    } else {
+                        dataListsShare.setPoster(t3.get(request.getUserVisits()));
+                    }
+                }
+                //背景海报顺序
+                List<ListeningPlanNewBackgroupPoster> qs = f.getT4().stream()
+                        .sorted(Comparator.comparing(ListeningPlanNewBackgroupPoster::index))
+                        .collect(Collectors.toList());
+                dataListsShare.setBackgroupPosterSum(qs.size());
+                if (!qs.isEmpty()) {
+                    //大于背景设置数
+                    if (qs.size() <= request.getUserVisits()) {
+                        Integer userVisits = request.getUserVisits();
+                        int v = userVisits % qs.size();
+                        dataListsShare.setFxSetting(qs.get(v));
+                        dataListsShare.setLink(f.getT1().link());//结束后开始设置link
+                    } else {
+                        dataListsShare.setFxSetting(qs.get(request.getUserVisits()));
+                        dataListsShare.setLink(null);
+                    }
+                }
+                String posterTemplate = dataListsShare.getPoster().posterTemplate();
+                JSONObject jsonObject;
+                try {
+                    jsonObject = JSONUtil.parseObj(posterTemplate);
+                } catch (Exception e) {
+                    throw new BaseException(e.getMessage() + "--解析海报模版--Errrrrrrrr" + posterTemplate);
+                }
+                GoRequest goRequest = new GoRequest();
+                BeanUtil.copyProperties(jsonObject, goRequest);
+                ListeningPlanNewBackgroupPoster fxSetting = dataListsShare.getFxSetting();
+                setQrcodeV(f, goRequest, fxSetting);
+                Mono<String> stringMono = generatePosterUrl(goRequest, generateCusqrcode(goRequest));
+                return Mono.zip(Mono.just(dataListsShare), stringMono).flatMap(fm -> {
+                    DataListsShare t1 = fm.getT1();
+                    t1.setPosterTemplate(null);
+                    t1.setPoster(null);
+                    t1.setUserVisits(request.getUserVisits());
+                    t1.setFxGenerateImagesUrl(fm.getT2());
+                    return Mono.just(t1);
+                });
+            });
+        });
+        return RStatus.success(dataListsShareMono);
+    }
+
+    private void setQrcodeV(reactor.util.function.Tuple5<ListeningPlanNew, PosterTemplate, List<Poster>, List<ListeningPlanNewBackgroupPoster>, StringBuilder> f, GoRequest goRequest, ListeningPlanNewBackgroupPoster fxSetting) {
+        if (Objects.nonNull(fxSetting)) {
+            Optional<Item> first = goRequest.getItem().stream().filter(fz -> "qrcode".equals(fz.getT())).findFirst();
+            if (first.isPresent()) {
+                Item item = first.get();
+                Boolean isRandom = item.getIsRandom();
+                if (isRandom && Objects.nonNull(fxSetting.status())
+                        && fxSetting.status() == 1
+                        && Objects.nonNull(fxSetting.serviceGroupType())
+                        && fxSetting.serviceGroupType() == 2) {
+                    String kefu = fxSetting.kefu();
+                    if (Objects.nonNull(kefu)
+                            && kefu.contains("[")
+                            && kefu.contains("]")) {
+                        JSONArray jsonArray = JSONUtil.parseArray(kefu);
+                        if (!jsonArray.isEmpty()) {
+                            String s = jsonArray.get(0, String.class);
+                            item.setV(s);
+                            item.setName("客服二维码");
+                        }
+                    } else {
+                        throw new BaseException("设置qrcode 上传图片为空");
+                    }
+                } else if (Objects.nonNull(fxSetting.status()) && fxSetting.status() == 0) {
+                    item.setV(f.getT5().toString());
+                    item.setName("H5二维码");
+                }
+            }
+        }
+    }
+
+    public Mono<StringBuilder> getQrcode( Mono<ListeningPlanNew> code) {
+        return code.flatMap(f9 -> Mono.zip(code, template.select(Query.query(Criteria.where("group_type_id").is(f9.groupId())
+                        .and("status").is(1).and("type").is(1)
+                .and("group_type").is(1)
+                .and("deleted_at").isNull()), DomainSelect.class)
+                        .collectList()
+                        .switchIfEmpty(Mono.just(List.of())), (a, b) -> {
+                    StringBuilder stringBuilder = new StringBuilder();
+                    if (Objects.nonNull(b) && !b.isEmpty()) {
+                        DomainSelect domainSelect = b.get(RandomUtil.randomInt(0, b.size()));
+                        stringBuilder.append("http://");
+                        stringBuilder.append(get6Str());
+                        stringBuilder.append(".");
+                        stringBuilder.append(domainSelect.domain());
+                        stringBuilder.append("/index.html?code=");
+                        stringBuilder.append(a.code());
+                        stringBuilder.append("&sk=");
+                        stringBuilder.append(IdUtil.fastSimpleUUID());
+                    }else {
+                        throw new BaseException("二维码链接:::通过计划id:"+a.listeningPlanNewId() +"的营销类型查询域名为空");
+                    }
+                    return stringBuilder;
+                })
+        );
+    }
+
+    public Mono<String> generatePosterUrl(GoRequest goRequest,Mono<List<StringBuilder>> stringBuilderMono){
+
+        Optional<Item> firstImage = goRequest.getItem().stream().filter(ft -> "image".equals(ft.getT())).findFirst();
+        Long imageGroupId=0L;
+        if (firstImage.isPresent() && Objects.nonNull(firstImage.get().getGroupTypeIdSc())) {
+            imageGroupId=firstImage.get().getGroupTypeIdSc();
+        }
+        Optional<Item> firstImage1 = goRequest.getItem().stream().filter(ft -> "text".equals(ft.getT())).findFirst();
+        Long imageGroupId1=0L;
+        if (firstImage1.isPresent() && Objects.nonNull(firstImage1.get().getGroupTypeIdSc())) {
+            imageGroupId1=firstImage1.get().getGroupTypeIdSc();
+        }
+        Optional<Item> firstImage2 = goRequest.getItem().stream().filter(ft -> "cover".equals(ft.getT())).findFirst();
+        Long imageGroupId2=0L;
+        if (firstImage2.isPresent() && Objects.nonNull(firstImage2.get().getGroupTypeIdSc())) {
+            imageGroupId2=firstImage2.get().getGroupTypeIdSc();
+        }
+        Long imageGroupIdBj=0L;
+        if(goRequest.getIsRandom()){
+            imageGroupIdBj=goRequest.getGroupTypeIdSc();
+        }
+        return  getStringMonoOut(goRequest,
+                stringBuilderMono,
+                getBgImageYx(imageGroupIdBj),
+                getFmImageListsYx(imageGroupId),
+                getTextListsYx(imageGroupId1),
+                getImageTypeYx(imageGroupId2),
+                getTextListsTitleH5(goRequest));
+    }
+
+    private Mono<List<ListeningPlanNewBackgroupPoster>> getPlanNewBackgroupPoster(Mono<ListeningPlanNew> code) {
+        return code.flatMap(plan -> template.select(Query.query(Criteria.where("poster_template_id")
+                .is(plan.posterTemplateId())).sort(Sort.by(Sort.Order.asc("idx"))), ListeningPlanNewBackgroupPoster.class)
+                .collectList());
+    }
+    private Mono<PosterTemplate> getPoster_template_id(Mono<ListeningPlanNew> code) {
+        return code.flatMap(plan -> template.selectOne(Query.query(Criteria.where("poster_template_id")
+                .is(plan.posterTemplateId())), PosterTemplate.class));
+    }
+    private Mono<List<Poster>> getPoster(Mono<ListeningPlanNew> code) {
+        return code.flatMap(plan -> template.select(Query.query(Criteria.where("poster_template_id")
+                .is(plan.posterTemplateId())).sort(Sort.by(Sort.Order.asc("created_at"))), Poster.class).collectList());
+    }
+    public Mono<String> getStringMonoOut(GoRequest goRequest,
+                                         Mono<List<StringBuilder>> stringBuilderMono,
+                                         Mono<List<Image>> bgImage,
+                                         Mono<List<Image>> fmImage,
+                                         Mono<List<Material>> text,
+                                         Mono<List<Image>> fm1,
+                                         Mono<List<Material>> title) {
+        Mono<String> stringMono = Mono.zip(bgImage, fmImage, text, stringBuilderMono,fm1,title).flatMap(f -> {
+            List<Material> t6 = f.getT6().stream().filter(ft->Objects.nonNull(ft.id())).collect(Collectors.toList());
+            if (Objects.nonNull(t6) &&!t6.isEmpty()) {
+                Optional.ofNullable(t6.get(RandomUtil.randomInt(0,t6.size()))).ifPresent(material -> goRequest.getItem().stream()
+                        .filter(ff -> "title".equals(ff.getT()) && ff.getIsRandom())
+                        .findFirst()
+                        .ifPresent(item -> {item.setV(material.content());}));
+            }else {
+                Optional<Item> first = goRequest.getItem().stream()
+                        .filter(ff -> "title".equals(ff.getT()) && ff.getIsRandom())
+                        .findFirst();
+                if (first.isPresent()) {
+                    throw new BaseException("海报标题素材为空");
+                }
+            }
+            List<StringBuilder> t4 = f.getT4();
+            if (Objects.nonNull(t4) && !t4.isEmpty()) {
+                goRequest.getItem().stream().filter(fc->"cusqrcode".equals(fc.getT())).forEach(fe->fe.setName("H5二维码"));
+            }else{
+                goRequest.getItem().stream().filter(fc->"cusqrcode".equals(fc.getT())).forEach(fe->fe.setName("客服二维码"));
+            }
+            Optional<Item> first2 = goRequest
+                    .getItem()
+                    .stream()
+                    .filter(fc -> "cusqrcode".equals(fc.getT()) && (Objects.isNull(fc.getV()) || "".equals(fc.getV())))
+                    .findFirst();
+            if (first2.isPresent()) {
+                throw new BaseException("自定义二维码素材为空");
+            }
+            List<Image> t1 = f.getT1();
+            if (goRequest.getIsRandom()) {
+                if (t1.isEmpty()) {
+                    throw new BaseException("背景素材为空");
+                }
+                int i = RandomUtil.randomInt(0, t1.size());
+                Image image = t1.get(i);
+                goRequest.setBg_img_src(image.image());
+            }
+            //封面
+            List<Image> t5 = f.getT5().stream().filter(ft->Objects.nonNull(ft.id())).collect(Collectors.toList());
+            if (Objects.nonNull(t5) &&!t5.isEmpty()) {
+                goRequest.getItem().stream().filter(ff -> "cover".equals(ff.getT()) && ff.getIsRandom()).findFirst()
+                        .ifPresent(item -> item.setV(t5.get(RandomUtil.randomInt(0, t5.size())).image()));
+            }else {
+                Optional<Item> first1 = goRequest.getItem().stream().filter(ff -> "cover".equals(ff.getT()) && ff.getIsRandom()).findFirst();
+                if (first1.isPresent()) {
+                    throw new BaseException("群封面素材为空");
+                }
+            }
+            //图片
+            List<Image> t2 = f.getT2().stream().filter(ft->Objects.nonNull(ft.id())).collect(Collectors.toList());
+            if (Objects.nonNull(t2) &&!t2.isEmpty()) {
+                Optional.ofNullable(t2.get(RandomUtil.randomInt(0, t2.size()))).ifPresent(image -> goRequest.getItem().stream()
+                        .filter(ff -> "image".equals(ff.getT()) && ff.getIsRandom() )
+                        .findFirst()
+                        .ifPresent(item -> item.setV(image.image())));
+            }else {
+                Optional<Item> first1 = goRequest.getItem().stream()
+                        .filter(ff -> "image".equals(ff.getT()) && ff.getIsRandom())
+                        .findFirst();
+                if (first1.isPresent()) {
+                    throw new BaseException("图片素材为空");
+                }
+            }
+            //文本
+            List<Material> t3 = f.getT3().stream().filter(ft->Objects.nonNull(ft.id())).collect(Collectors.toList());
+            if (Objects.nonNull(t3) &&!t3.isEmpty()) {
+                Optional.ofNullable(t3.get(RandomUtil.randomInt(0,t3.size()))).ifPresent(material -> goRequest.getItem().stream()
+                        .filter(ff -> "text".equals(ff.getT()) && ff.getIsRandom())
+                        .findFirst()
+                        .ifPresent(item -> {item.setV(material.content());}));
+            }else{
+                Optional<Item> first1 = goRequest.getItem().stream()
+                        .filter(ff -> "text".equals(ff.getT()) && ff.getIsRandom())
+                        .findFirst();
+                if (first1.isPresent()) {
+                    throw new BaseException("文字素材为空");
+                }
+            }
+            String ret = goGenerateStr(JSONUtil.toJsonStr(JSONUtil.toJsonStr(goRequest)));
+            if (Objects.nonNull(ret)) {
+                JSONObject jsonObject1;
+                try {
+                    jsonObject1 =  JSONUtil.parseObj(ret);
+                }catch (Exception e){
+                    throw new BaseException(e.getMessage() +"--解析错误结果--"+JSONUtil.parseObj(goRequest));
+                }
+                if (jsonObject1.containsKey("code") && jsonObject1.get("code", Integer.class) == 0 && jsonObject1.containsKey("data")) {
+                    JSONObject data = jsonObject1.get("data", JSONObject.class);
+                    if (data.containsKey("Url")) {
+                        return Mono.just(data.get("Url", String.class)) ;
+                    }else {
+                        throw new BaseException("--生成海报Url结果异常::::"+jsonObject1);
+                    }
+                }else {
+                    throw new BaseException("--生成海报code结果异常::::"+jsonObject1);
+                }
+            }else {
+                throw new BaseException("--生成海报结果null异常::::"+ret);
+            }
+        });
+        return stringMono;
+    }
+    public Mono<List<StringBuilder>> generateCusqrcode(GoRequest goRequest) {
+        List<Item> collect = goRequest.getItem().stream().filter(f -> "cusqrcode".equals(f.getT())
+                && Objects.nonNull(f.getPlanId())
+                && f.getIsRandom())
+                .collect(Collectors.toList());
+        Mono<List<StringBuilder>> stringBuilderMono =null;
+        if (Objects.nonNull(collect) && !collect.isEmpty()) {
+            List<Long> collect1 = collect.stream().map(Item::getPlanId).collect(Collectors.toList());
+            stringBuilderMono = template.select(Query.query(Criteria.where("listening_plan_new_id").in(collect1)), ListeningPlanNew.class)
+                    .flatMap(f -> Mono.zip(Mono.just(f), template.select(Query.query(Criteria.where("group_type_id").is(f.groupId())
+                                    .and("status").is(1)
+                                    .and("type").is(1)
+                                    .and("deleted_at").isNull()), DomainSelect.class)
+                                    .collectList()
+                                    .switchIfEmpty(Mono.just(List.of())), (a, b) -> {
+                                StringBuilder stringBuilder = new StringBuilder();
+                                if (Objects.nonNull(b) && !b.isEmpty()) {
+                                    DomainSelect domainSelect = b.get(RandomUtil.randomInt(0, b.size()));
+                                    stringBuilder.append("http://");
+                                    stringBuilder.append( get6Str());
+                                    stringBuilder.append(".");
+                                    stringBuilder.append(domainSelect.domain());
+                                    stringBuilder.append("/index.html?code=");
+                                    stringBuilder.append(a.code());
+                                    stringBuilder.append("&sk=");
+                                    stringBuilder.append(IdUtil.fastSimpleUUID());
+                                }else {
+                                    throw new BaseException("通过计划id:"+a.listeningPlanNewId() +"的营销类型查询域名为空");
+                                }
+                                Optional<Item> first = collect.stream()
+                                        .filter(ft -> ft.getPlanId()
+                                                .equals(f.listeningPlanNewId()) && (Objects.isNull(ft.getV()) || "".equals(ft.getV()))).findFirst();
+                                first.ifPresent(item -> item.setV(stringBuilder.toString()));
+                                return stringBuilder;
+                            })
+                    ).collectList();
+        }
+        if (Objects.isNull(stringBuilderMono)) {
+            return Mono.just(List.of());
+        }
+        return stringBuilderMono;
+    }
+    private Mono<List<Material>> getTextListsTitleH5(GoRequest goRequest) {
+
+        Optional<Item> first = goRequest.getItem().stream().filter(ft -> "title".equals(ft.getT())).findFirst();
+        if (first.isPresent() && Objects.nonNull(first.get().getGroupTypeIdSc())) {
+            return template.select(Query.query(Criteria.where("type").is(6)
+                    .and("group_type_id").is(first.get().getGroupTypeIdSc())
+                    .and("deleted_at").isNull()), Material.class)
+                    .collectList();
+        }else {
+            return   Mono.just(List.of(getMaterialNull()));
+        }
+    }
+    private Mono<List<Material>> getTextListsYx(Long id) {
+        return template.select(Query.query(Criteria.where("type").is(14)
+                .and("group_type_id").is(id)
+                .and("group_type").is(1).and("deleted_at").isNull()), Material.class).collectList();
+    }
+    private Mono<List<Image>> getBgImageYx(Long id) {
+        return template.select(Query.query(Criteria.where("type").is(2)
+                .and("group_type").is(1).and("group_type_id").is(id)
+                .and("deleted_at").isNull()), Image.class).collectList();
+    }
+    private Mono<List<Image>> getFmImageListsYx(Long id) {
+        return template.select(Query.query(Criteria.where("type").is(10)
+                .and("group_type_id").is(id).and("group_type")
+                .is(1).and("deleted_at").isNull()), Image.class).collectList();
+    }
+    private Mono<List<Image>> getImageTypeYx(Long id){
+        return template.select(Query.query(Criteria.where("type").is(1) .and("group_type_id").is(id).and("group_type").is(1).and("deleted_at").isNull()), Image.class).collectList();
+    }
+    /**
+     * 计划保存修改生成图片
+     * @param goRequest
+     * @param stringBuilderMono
+     * @param qsSetting
+     * @return
+     */
+
+    public Mono<String> saveAndUpdatePlanGenerateImage0(GoRequest goRequest,
+                                                        Mono<List<StringBuilder>> stringBuilderMono,
+                                                        ServiceGroupSettingItemRequest qsSetting,
+                                                        PlanReq saveRequest ){
+
+        Optional<Item> firstImage = goRequest.getItem().stream().filter(ft -> "image".equals(ft.getT())).findFirst();
+        Long imageGroupId=0L;
+        if (firstImage.isPresent() && Objects.nonNull(firstImage.get().getGroupTypeIdSc())) {
+            imageGroupId=firstImage.get().getGroupTypeIdSc();
+        }
+        Optional<Item> firstImage1 = goRequest.getItem().stream().filter(ft -> "text".equals(ft.getT())).findFirst();
+        Long imageGroupId1=0L;
+        if (firstImage1.isPresent() && Objects.nonNull(firstImage1.get().getGroupTypeIdSc())) {
+            imageGroupId1=firstImage1.get().getGroupTypeIdSc();
+        }
+        Optional<Item> firstImage2 = goRequest.getItem().stream().filter(ft -> "cover".equals(ft.getT())).findFirst();
+        Long imageGroupId2=0L;
+        if (firstImage2.isPresent() && Objects.nonNull(firstImage2.get().getGroupTypeIdSc())) {
+            imageGroupId2=firstImage2.get().getGroupTypeIdSc();
+        }
+        Long imageGroupIdBj=0L;
+        if(goRequest.getIsRandom()){
+            imageGroupIdBj=goRequest.getGroupTypeIdSc();
+        }
+        return   saveAndUpdatePlanGenerateImage1(goRequest, stringBuilderMono,
+                getBgImage(imageGroupIdBj),
+                getImageSaveOrUpdatePlan(imageGroupId),
+                getTextListsPlan(imageGroupId1),
+                getImageType1Plan(imageGroupId2),
+                qsSetting,
+                saveRequest,
+                getTextListsTitleSaveOrUpdatePlan( goRequest));
+    }
+
+    private Material getMaterialNull() {
+        return new Material(null, null, null, null, null, null, null, null, null, null, null);
+    }
+    private Mono<List<Material>> getTextListsTitleSaveOrUpdatePlan(GoRequest goRequest) {
+        Optional<Item> first = goRequest.getItem().stream().filter(ft -> "title".equals(ft.getT())).findFirst();
+        if (first.isPresent() && Objects.nonNull(first.get().getGroupTypeIdSc())) {
+            return template.select(Query.query(Criteria.where("type").is(6)
+                    .and("group_type_id").is(first.get().getGroupTypeIdSc())
+                    .and("deleted_at").isNull()), Material.class)
+                    .collectList();
+        }else {
+            return   Mono.just(List.of(getMaterialNull()));
+        }
+    }
+    private Mono<List<Image>> getImageType1Plan(Long groupTypeId){
+        return template.select(Query.query(Criteria.where("type").is(1)
+                .and("group_type_id").is(groupTypeId)
+                .and("size_type").is(1)
+                .and("deleted_at").isNull()), Image.class).collectList();
+    }
+    private Mono<List<Material>> getTextListsPlan(Long groupTypeId) {
+        return template.select(Query.query(Criteria.where("type").is(14)
+                .and("group_type_id").is(groupTypeId)
+                .and("deleted_at").isNull()), Material.class)
+                .collectList();
+    }
+    private Mono<List<Image>> getImageSaveOrUpdatePlan(Long id) {
+        return template.select(Query.query(Criteria.where("type").is(10).and("group_type_id").is(id).and("deleted_at").isNull()), Image.class)
+                .collectList();
+    }
+    public Mono<String> saveAndUpdatePlanGenerateImage1(GoRequest goRequest,
+                                                        Mono<List<StringBuilder>> stringBuilderMono,
+                                                        Mono<List<Image>> bgImage,
+                                                        Mono<List<Image>> images,
+                                                        Mono<List<Material>> text,
+                                                        Mono<List<Image>> coverFm,
+                                                        ServiceGroupSettingItemRequest qsSetting,
+                                                        PlanReq saveRequest,
+                                                        Mono<List<Material>> title) {
+        Mono<String> stringMono = Mono.zip(bgImage, images, text, stringBuilderMono,coverFm,getQrcode(saveRequest),title).flatMap(f -> {
+            List<StringBuilder> t4 = f.getT4();//自定义二维码
+            if (Objects.nonNull(t4) && !t4.isEmpty()) {
+                goRequest.getItem().stream().filter(fc->"cusqrcode".equals(fc.getT())).forEach(fe->fe.setName("H5二维码"));
+            }else{
+                goRequest.getItem().stream().filter(fc->"cusqrcode".equals(fc.getT())).forEach(fe->fe.setName("客服二维码"));
+            }
+
+            Optional<Item> first2 = goRequest.getItem().stream().filter(fc -> "cusqrcode".equals(fc.getT()) && (Objects.isNull(fc.getV()) || "".equals(fc.getV()))).findFirst();
+            if (first2.isPresent()) {
+                throw new BaseException("自定义二维码素材为空");
+            }
+            //背景
+            List<Image> t1 = f.getT1();
+            if (goRequest.getIsRandom()) {
+                if (t1.isEmpty()) {
+                    throw new BaseException("背景素材为空");
+                }
+                int i = RandomUtil.randomInt(0, t1.size());
+                Image image = t1.get(i);
+                goRequest.setBg_img_src(image.image());
+            }
+            //海报标题
+            List<Material> t7 = f.getT7().stream().filter(ft->Objects.nonNull(ft.id())).collect(Collectors.toList());
+            if (Objects.nonNull(t7) &&!t7.isEmpty()) {
+                Optional.ofNullable(t7.get(RandomUtil.randomInt(0,t7.size()))).ifPresent(material -> goRequest.getItem().stream()
+                        .filter(ff -> "title".equals(ff.getT()) && ff.getIsRandom())
+                        .findFirst()
+                        .ifPresent(item -> item.setV(material.content())));
+            }else {
+                Optional<Item> first = goRequest.getItem().stream()
+                        .filter(ff -> "title".equals(ff.getT()) && ff.getIsRandom())
+                        .findFirst();
+                if (first.isPresent()) {
+                    throw new BaseException("海报标题素材为空");
+                }
+            }
+            //群封面
+            List<Image> t5 = f.getT5().stream().filter(ft->Objects.nonNull(ft.id())).collect(Collectors.toList());
+            if (Objects.nonNull(t5) &&!t5.isEmpty()) {
+                goRequest.getItem().stream().filter(ff -> "cover".equals(ff.getT()) && ff.getIsRandom()).findFirst()
+                        .ifPresent(item -> item.setV(t5.get(RandomUtil.randomInt(0, t5.size())).image()));
+            }else {
+                Optional<Item> first1 = goRequest.getItem().stream().filter(ff -> "cover".equals(ff.getT()) && ff.getIsRandom()).findFirst();
+                if (first1.isPresent()) {
+                    throw new BaseException("群封面素材为空");
+                }
+            }
+            //二维码链接
+            Optional<Item> first5 = goRequest.getItem().stream().filter(f1 -> "qrcode".equals(f1.getT())).findFirst();
+            if (first5.isPresent()) {
+                Item item = first5.get();
+                Boolean isRandom = item.getIsRandom();
+                if (isRandom && Objects.nonNull(qsSetting.getStatus()) &&  qsSetting.getStatus()==1
+                        &&Objects.nonNull(qsSetting.getServiceGroupType()) &&  qsSetting.getServiceGroupType()==2 ) {
+                    String kefu = qsSetting.getKefu();
+                    if (Objects.nonNull(kefu) && kefu.contains("[") &&  kefu.contains("]")  ) {
+                        JSONArray jsonArray = JSONUtil.parseArray(kefu);
+                        if (!jsonArray.isEmpty()) {
+                            String s = jsonArray.get(0, String.class);
+                            item.setV(s);
+                            item.setName("客服二维码");
+                        }
+                    }else {
+                        throw new BaseException("客服二维码 上传图片 为空");
+                    }
+                }else if(Objects.nonNull(qsSetting.getStatus()) &&  qsSetting.getStatus()==0 ) {
+                    StringBuilder t6 = f.getT6();
+                    if ("".equals(t6)) {
+                        throw new BaseException("获取H5链接为空");
+                    }
+                    item.setV(t6.toString());
+                    item.setName("H5二维码");
+                }
+            }
+            //图片
+            List<Image> t2 = f.getT2().stream().filter(ft->Objects.nonNull(ft.id())).collect(Collectors.toList());
+            if (Objects.nonNull(t2) &&!t2.isEmpty()) {
+                Optional.ofNullable(t2.get(RandomUtil.randomInt(0, t2.size()))).ifPresent(image -> goRequest.getItem().stream()
+                        .filter(ff -> "image".equals(ff.getT()) && ff.getIsRandom() )
+                        .findFirst()
+                        .ifPresent(item -> item.setV(image.image())));
+            }else {
+                Optional<Item> first1 = goRequest.getItem().stream()
+                        .filter(ff -> "image".equals(ff.getT()) && ff.getIsRandom())
+                        .findFirst();
+                if (first1.isPresent()) {
+                    throw new BaseException("图片素材为空");
+                }
+            }
+            //文本
+            List<Material> t3 = f.getT3().stream().filter(ft->Objects.nonNull(ft.id())).collect(Collectors.toList());
+            if (Objects.nonNull(t3) &&!t3.isEmpty()) {
+                Optional.ofNullable(t3.get(RandomUtil.randomInt(0,t3.size()))).ifPresent(material -> goRequest.getItem().stream()
+                        .filter(ff -> "text".equals(ff.getT()) && ff.getIsRandom())
+                        .findFirst()
+                        .ifPresent(item -> {item.setV(material.content());}));
+            }else{
+                Optional<Item> first1 = goRequest.getItem().stream()
+                        .filter(ff -> "text".equals(ff.getT()) && ff.getIsRandom())
+                        .findFirst();
+                if (first1.isPresent()) {
+                    throw new BaseException("文字素材为空");
+                }
+            }
+            String s1 = JSONUtil.toJsonStr(goRequest);
+            System.out.println(s1);
+            String ret = goGenerateStr(s1);
+            System.out.println(ret);
+            String url=ret;
+            JSONObject jsonObject1 = JSONUtil.parseObj(ret);
+            if (jsonObject1.containsKey("code") && jsonObject1.get("code", Integer.class) == 0 && jsonObject1.containsKey("data")) {
+                JSONObject data = jsonObject1.get("data", JSONObject.class);
+                if (data.containsKey("Url")) {
+                    url = data.get("Url", String.class);
+                }
+            }
+            return Mono.just(url);
+        });
+        return stringMono;
+    }
+
+    public String goGenerateStr(String temStr){
+        String body="";
+        try {
+            body = HttpUtil.post(value + "/api/image/createImage",temStr,100000);
+            return body;
+        } catch (Exception e) {
+            throw new BaseException(e.getMessage() + "body:::" +body);
+        }
+
+
+
+    }
+    public Mono<StringBuilder> getQrcode(PlanReq saveRequest) {
+        if (Objects.isNull(saveRequest.getPlanNewId())|| "".equals(saveRequest.getPlanNewId())) {
+            return template.select(Query.query(Criteria.where("group_type_id").is(saveRequest.getGroupId())
+                    .and("status").is(1)
+                    .and("type").is(1)
+                    .and("deleted_at").isNull()), DomainSelect.class)
+                    .collectList()
+                    .switchIfEmpty(Mono.just(List.of())).flatMap(b->{
+                        StringBuilder stringBuilder = new StringBuilder();
+                        getUrl(saveRequest, b, stringBuilder);
+                        return Mono.just(stringBuilder);
+                    });
+        }else{
+            return template.selectOne(Query.query(Criteria.where("listening_plan_new_id").is(saveRequest.getPlanNewId())), ListeningPlanNew.class)
+                    .flatMap(f9 -> Mono.zip(Mono.just(f9), template.select(Query.query(Criteria.where("group_type_id").is(f9.groupId())
+                                    .and("status").is(1)
+                            .and("type").is(1)
+                            .and("deleted_at").isNull()), DomainSelect.class)
+                                    .collectList()
+                                    .switchIfEmpty(Mono.just(List.of())), (a, b) -> {
+                                StringBuilder stringBuilder = new StringBuilder();
+                        getUrl1(a, b, stringBuilder);
+                        return stringBuilder;
+                            })
+                    );
+        }
+    }
+
+    private void getUrl1(ListeningPlanNew a, List<DomainSelect> b, StringBuilder stringBuilder) {
+        if (Objects.nonNull(b) && !b.isEmpty()) {
+            DomainSelect domainSelect = b.get(RandomUtil.randomInt(0, b.size()));
+            stringBuilder.append("http://");
+            stringBuilder.append(get6Str());
+            stringBuilder.append(".");
+            stringBuilder.append(domainSelect.domain());
+            stringBuilder.append("/index.html?code=");
+            stringBuilder.append(a.code());
+            stringBuilder.append("&sk=");
+            stringBuilder.append(IdUtil.fastSimpleUUID());
+        }else {
+            throw new BaseException("通过计划id:"+a.listeningPlanNewId() +"的营销类型查询域名为空");
+        }
+    }
+    private void getUrl(PlanReq saveRequest, List<DomainSelect> b, StringBuilder stringBuilder) {
+        if (Objects.nonNull(b) && !b.isEmpty()) {
+            DomainSelect domainSelect = b.get(RandomUtil.randomInt(0, b.size()));
+            stringBuilder.append("http://");
+            stringBuilder.append(get6Str());
+            stringBuilder.append(".");
+            stringBuilder.append(domainSelect.domain());
+            stringBuilder.append("/index.html?code=");
+            stringBuilder.append(saveRequest.getCode());
+            stringBuilder.append("&sk=");
+            stringBuilder.append(IdUtil.fastSimpleUUID());
+        }else {
+            throw new BaseException("通过计划id:"+saveRequest.getPlanNewId() +"的营销类型查询域名为空");
+        }
+    }
+
+
+    private String get6Str() {
+        String string = RandomUtil.randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6);
+        return string;
+    }
+    //背景
+    private Mono<List<Image>> getBgImage(Long id) {
+        return template.select(Query.query(Criteria.where("type").is(2).and("group_type_id").is(id).and("deleted_at").isNull()), Image.class)
+                .collectList();
+    }
+}

+ 33 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/service/listening/ListeningPlanServiceInterface.java

@@ -0,0 +1,33 @@
+package com.webflux.launchadmin.mysql.service.listening;
+
+import com.webflux.launchadmin.mysql.controller.listening.req.*;
+import com.webflux.launchadmin.mysql.controller.listening.res.DataListsShare;
+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.PlanReq;
+import com.webflux.launchadmin.mysql.controller.planNew.req.PlanReqPage;
+import com.webflux.launchadmin.mysql.controller.planNew.req.ServiceGroupSettingItemRequest;
+import com.webflux.launchadmin.mysql.entity.listening.ListeningAudio;
+import com.webflux.launchadmin.mysql.entity.listening.ListeningPlanNew;
+import com.webflux.launchadmin.mysql.entity.planNew.GroupType;
+import com.webflux.launchadmin.mysql.entity.planNew.PlanNew;
+import com.webflux.launchadmin.mysql.service.planNew.structure.GoRequest;
+import com.webflux.launchcommon.returnObj.Paged;
+import com.webflux.launchcommon.returnObj.RStatus;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+public interface ListeningPlanServiceInterface {
+     Mono<RStatus<List<GroupType>>> groupTypeSlt ( String name);
+    Mono<RStatus<Paged<ListeningPlanNewRes2>>> page(PlanReqPage request);
+    Mono<RStatus<String>> savePlan(PlanReq saveRequest);
+    Mono<List<StringBuilder>> setCusqrcodeRtUrl(GoRequest goRequest);
+    Mono<RStatus<ListeningAudio>> saveOrUpdateAudio(ListeningAudioReq saveRequest);
+    Mono<RStatus<Paged<ListeningAudioRes>>> audioList(ListeningAudioReqPage request);
+    Mono<RStatus<String>> copyById(String listeningPlanNewId);
+    Mono<RStatus<ListeningDataLists>> LandingPageList(OutListeningRequest outListeningRequest);
+    Mono<RStatus<DataListsShare>> share(OutListeningShareRequest outListeningRequest);
+}

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

@@ -0,0 +1,56 @@
+package com.webflux.launchadmin.mysql.service.planNew;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.webflux.launchadmin.config.BaseContextHandler;
+import com.webflux.launchadmin.global.BaseException;
+import com.webflux.launchadmin.mysql.controller.listening.req.*;
+import com.webflux.launchadmin.mysql.controller.listening.res.DataListsShare;
+import com.webflux.launchadmin.mysql.controller.listening.res.ListeningPlanNewRes;
+import com.webflux.launchadmin.mysql.controller.planNew.req.PlanReqPage;
+import com.webflux.launchadmin.mysql.entity.listening.ListeningAudio;
+import com.webflux.launchadmin.mysql.entity.listening.ListeningPlanNew;
+import com.webflux.launchadmin.mysql.entity.listening.ListeningPlanNewBackgroupPoster;
+import com.webflux.launchadmin.mysql.entity.planNew.*;
+import com.webflux.launchadmin.mysql.service.listening.ListeningPlanServiceInterface;
+import com.webflux.launchadmin.mysql.service.planNew.structure.GoRequest;
+import com.webflux.launchadmin.mysql.service.planNew.structure.Item;
+import com.webflux.launchcommon.returnObj.Paged;
+import com.webflux.launchcommon.returnObj.RStatus;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
+import org.springframework.data.relational.core.query.Criteria;
+import org.springframework.data.relational.core.query.Query;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.time.ZonedDateTime;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class PlanServiceImpl implements PlanServiceInterface {
+    @Value("${go.data.createImage}")
+    private String value;
+
+    @Resource
+    private R2dbcEntityTemplate template;
+
+
+
+}

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

@@ -0,0 +1,19 @@
+package com.webflux.launchadmin.mysql.service.planNew;
+
+import com.webflux.launchadmin.mysql.controller.listening.req.*;
+import com.webflux.launchadmin.mysql.controller.listening.res.DataListsShare;
+import com.webflux.launchadmin.mysql.controller.listening.res.ListeningPlanNewRes;
+import com.webflux.launchadmin.mysql.controller.planNew.req.PlanReqPage;
+import com.webflux.launchadmin.mysql.entity.listening.ListeningAudio;
+import com.webflux.launchadmin.mysql.entity.listening.ListeningPlanNew;
+import com.webflux.launchadmin.mysql.entity.planNew.GroupType;
+import com.webflux.launchadmin.mysql.service.planNew.structure.GoRequest;
+import com.webflux.launchcommon.returnObj.Paged;
+import com.webflux.launchcommon.returnObj.RStatus;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+public interface PlanServiceInterface {
+
+}

+ 14 - 5
launch-admin/src/main/java/com/webflux/launchadmin/mysql/service/planNew/goGenerate/GoGenerateService.java

@@ -130,7 +130,8 @@ public class GoGenerateService {
         return template.select(Query.query(Criteria.where("type").is(1)
                 .and("group_type_id").is(groupTypeId)
                 .and("size_type").is(1)
-                .and("deleted_at").isNull()), Image.class).collectList();
+                .and("deleted_at").isNull()), Image.class)
+                .collectList();
     }
     private Mono<List<Material>> getTextLists() {
         return template.select(Query.query(Criteria.where("type").is(14).and("deleted_at").isNull()), Material.class)
@@ -198,7 +199,8 @@ public class GoGenerateService {
 
     //背景
     private Mono<List<Image>> getBgImage(Long id) {
-        return template.select(Query.query(Criteria.where("type").is(2).and("group_type_id").is(id).and("deleted_at").isNull()), Image.class)
+        return template.select(Query.query(Criteria.where("type").is(2).and("group_type_id").is(id)
+                .and("deleted_at").isNull()), Image.class)
                 .collectList();
     }
 
@@ -628,7 +630,7 @@ public class GoGenerateService {
         return stringMono;
     }
     public Mono<StringBuilder> getStringBuilderMono(PlanReq saveRequest) {
-        if (Objects.isNull(saveRequest.getPlanNewId())) {
+        if (Objects.isNull(saveRequest.getPlanNewId()) || "".equals(saveRequest.getPlanNewId())) {
            return template.select(Query.query(Criteria.where("group_type_id").is(saveRequest.getGroupId())
                     .and("status").is(1).and("type").is(1).and("deleted_at").isNull()), DomainSelect.class)
                     .collectList()
@@ -755,7 +757,8 @@ public class GoGenerateService {
             }else{
                 goRequest.getItem().stream().filter(fc->"cusqrcode".equals(fc.getT())).forEach(fe->fe.setName("客服二维码"));
             }
-            Optional<Item> first2 = goRequest.getItem().stream().filter(fc -> "cusqrcode".equals(fc.getT()) && (Objects.isNull(fc.getV()) || "".equals(fc.getV()))).findFirst();
+            Optional<Item> first2 = goRequest.getItem()
+                    .stream().filter(fc -> "cusqrcode".equals(fc.getT()) && (Objects.isNull(fc.getV()) || "".equals(fc.getV()))).findFirst();
             if (first2.isPresent()) {
                 throw new BaseException("自定义二维码素材为空");
             }
@@ -1029,7 +1032,13 @@ public class GoGenerateService {
                 .collectList();
     }
     private Mono<List<Image>> getImageSaveOrUpdatePlan(Long id) {
-        return template.select(Query.query(Criteria.where("type").is(10).and("group_type_id").is(id).and("deleted_at").isNull()), Image.class)
+        return template.select(Query.query(Criteria.where("type").is(10)
+                .and("group_type_id").is(id)
+                .and("deleted_at").isNull()), Image.class)
                 .collectList();
     }
+
+    private Image getImage() {
+        return new Image(null, null, null, null, null, null, null, null, null, null, null);
+    }
 }

+ 1 - 1
launch-admin/src/main/resources/application.yml

@@ -1,5 +1,5 @@
 server:
-  port: 9800
+  port: 8800
 
 spring:
   application: