Просмотр исходного кода

Merge branch 'test' of http://git.mokasz.com/liuwei/launch-webFlux-platform into test

volta 2 лет назад
Родитель
Сommit
13e3f973dd
100 измененных файлов с 7449 добавлено и 34 удалено
  1. 34 0
      .gitignore
  2. BIN
      .mvn/wrapper/maven-wrapper.jar
  3. 2 0
      .mvn/wrapper/maven-wrapper.properties
  4. 11 0
      Dockerfile
  5. 29 0
      LICENSE
  6. 2 34
      README.md
  7. 26 0
      docker-compose.yml
  8. 33 0
      launch-admin/.gitignore
  9. BIN
      launch-admin/.mvn/wrapper/maven-wrapper.jar
  10. 2 0
      launch-admin/.mvn/wrapper/maven-wrapper.properties
  11. 308 0
      launch-admin/mvnw
  12. 0 0
      launch-admin/mvnw.cmd
  13. 238 0
      launch-admin/pom.xml
  14. 20 0
      launch-admin/src/main/java/com/webflux/launchadmin/LaunchAdminApplication.java
  15. 33 0
      launch-admin/src/main/java/com/webflux/launchadmin/config/AuthenticationFilter.java
  16. 13 0
      launch-admin/src/main/java/com/webflux/launchadmin/config/BaseConstants.java
  17. 79 0
      launch-admin/src/main/java/com/webflux/launchadmin/config/BaseContextHandler.java
  18. 220 0
      launch-admin/src/main/java/com/webflux/launchadmin/config/LoginWebFiter.java
  19. 25 0
      launch-admin/src/main/java/com/webflux/launchadmin/config/MyWebConfiguration.java
  20. 30 0
      launch-admin/src/main/java/com/webflux/launchadmin/config/PlumeLogilterConfig.java
  21. 13 0
      launch-admin/src/main/java/com/webflux/launchadmin/context/UserContext.java
  22. 70 0
      launch-admin/src/main/java/com/webflux/launchadmin/context/XxlSsoUser.java
  23. 26 0
      launch-admin/src/main/java/com/webflux/launchadmin/dispatcher/MailTask.java
  24. 28 0
      launch-admin/src/main/java/com/webflux/launchadmin/dispatcher/config/ScheduleConfig.java
  25. 33 0
      launch-admin/src/main/java/com/webflux/launchadmin/filter/TraceIdFilter.java
  26. 88 0
      launch-admin/src/main/java/com/webflux/launchadmin/global/BaseException.java
  27. 24 0
      launch-admin/src/main/java/com/webflux/launchadmin/global/GlobalExceptionHandler.java
  28. 52 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/OutController.java
  29. 101 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/TempAllController/TempAll0Controller.java
  30. 101 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/TempAllController/TempAll1Controller.java
  31. 12 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/TempAllController/request/PageRequset.java
  32. 75 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/groupUsers/GroupUsersController.java
  33. 12 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/groupUsers/res/DeleteRes.java
  34. 40 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/groupUsers/res/GroupUsersRes.java
  35. 219 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/lbIn/HomePageInController.java
  36. 19 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/lbIn/request/HomePageItemRequest.java
  37. 45 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/lbIn/request/HomePageItemSaveRequest.java
  38. 47 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/lbIn/request/HomePageItemUpdateRequest.java
  39. 13 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/lbIn/request/HomePageRequest.java
  40. 25 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/lbIn/request/HomePageSaveRequest.java
  41. 29 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/lbIn/request/HomePageUpdateRequest.java
  42. 139 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/lbOut/HomePageOutController.java
  43. 31 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/lbOut/request/HomePageItemOutRequest.java
  44. 10 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/lbOut/resp/DataList.java
  45. 139 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/ListeningPlanNewController.java
  46. 43 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/ListeningPlanNewOutController.java
  47. 29 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/H5ImageAndTextListening.java
  48. 36 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/ListeningAudioReq.java
  49. 16 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/ListeningAudioReqPage.java
  50. 39 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/ListeningAudioRes.java
  51. 34 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/ListeningDataLists.java
  52. 21 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/ListeningPlanReqPage.java
  53. 22 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/ListeningServiceGroupSettingItemRequest.java
  54. 11 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/OutListeningRequest.java
  55. 12 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/OutListeningShareRequest.java
  56. 66 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/req/PlanSaveReq.java
  57. 108 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/res/DataListsShare.java
  58. 67 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/res/ListeningPlanNewRes.java
  59. 13 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/res/ListeningPlanNewRes1.java
  60. 14 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/listening/res/ListeningPlanNewRes2.java
  61. 29 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/otherServices/OtherServicesController.java
  62. 8 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/otherServices/res/ByCodeGetImportDomainRes.java
  63. 331 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/PlanNewCommonController.java
  64. 913 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/PlanNewCommonOutController.java
  65. 1084 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/PlanNewController.java
  66. 1013 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/PlanNewOutController.java
  67. 8 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/AudioRequest.java
  68. 14 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/BackgroupRequest.java
  69. 11 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/HfoRequest.java
  70. 12 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/HftRequest.java
  71. 19 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/KefuRequest.java
  72. 29 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/OutDomainRequest.java
  73. 9 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PlanCodeRequest.java
  74. 26 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PlanNewCommonMaterialReq.java
  75. 25 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PlanNewCommonShareReq.java
  76. 163 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PlanReq.java
  77. 32 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PlanReqPage.java
  78. 15 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PosterPage.java
  79. 9 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PosterReq.java
  80. 19 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PosterRequest.java
  81. 15 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PosterTemPage.java
  82. 11 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PosterTemSelect.java
  83. 20 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PosterTemSelectSelf.java
  84. 13 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PosterTemplateRequset.java
  85. 8 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/ReturnLoopRequest.java
  86. 8 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/ServiceGroupRequest.java
  87. 22 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/ServiceGroupSettingItemRequest.java
  88. 30 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/ServiceGroupSettingRequest.java
  89. 23 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/BackgroupImageRes.java
  90. 9 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/DataList.java
  91. 64 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/DataLists.java
  92. 107 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/DataLists0.java
  93. 48 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/DataLists1.java
  94. 59 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/DataListsKefu.java
  95. 25 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/DomainSelectRes.java
  96. 17 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/GroupUserRes.java
  97. 21 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/H5ImageAndText.java
  98. 73 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/PlanNewAllRs.java
  99. 39 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/PlanNewBackgroupPosterAllRes.java
  100. 41 0
      launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/res/PlanNewCommonMaterialRes.java

+ 34 - 0
.gitignore

@@ -0,0 +1,34 @@
+logs
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/

BIN
.mvn/wrapper/maven-wrapper.jar


+ 2 - 0
.mvn/wrapper/maven-wrapper.properties

@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar

+ 11 - 0
Dockerfile

@@ -0,0 +1,11 @@
+FROM jdk21-alpine:3.18
+
+ARG env
+
+ENV ENVIRMENT=${env:+"dev"}
+ENV ENVIRMENT=${ENVIRMENT:-"prod"}
+
+COPY ./launch-admin/target/*.jar  /app/lbservice.jar
+
+
+CMD ["java","-Xms1g","-Xmx2g","-jar","-Dspring.profiles.active=${ENVIRMENT}", "/app/lbservice.jar","--server.port=8080"]

+ 29 - 0
LICENSE

@@ -0,0 +1,29 @@
+BSD 3-Clause License
+
+Copyright (c) 2022, 人间有味是清欢
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+
+* Neither the name of the copyright holder nor the names of its
+  contributors may be used to endorse or promote products derived from
+  this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 2 - 34
README.md

@@ -1,39 +1,7 @@
-# springboot3-r2dbc-demo
 
 #### 介绍
-
-- success:
-
     1. springboot 3,
     2. webFlux,
     3. r2dbc,
-    4. oracle,
-    5. openAPI 3;
-
-- fail:
-
-    1. GraalVM native, that duo to oracle-r2dbc unsupported.
-
-#### 软件架构
-
-软件架构说明
-
-#### 安装教程
-
-1. xxxx
-2. xxxx
-3. xxxx
-
-#### 使用说明
-
-1. xxxx
-2. xxxx
-3. xxxx
-
-#### 参与贡献
-
-1. Fork 本仓库
-2. 新建 Feat_xxx 分支
-3. 提交代码
-4. 新建 Pull Request
-
+    4. java21
+    

+ 26 - 0
docker-compose.yml

@@ -0,0 +1,26 @@
+version: "3.7"
+
+services:
+  galaxy-micro-service:
+    build:
+      context: .
+      dockerfile: ./Dockerfile
+    image: webflux:latest
+    container_name: webflux
+    healthcheck:
+      test: ["CMD-SHELL","curl --fail http://localhost:8080/actuator/health"]
+      interval: 10s
+      timeout: 5s
+      retries: 3
+    deploy:
+      resources:
+        limits:
+          memory: 2048M
+    ports:
+      - "8080:8080"
+    restart: always
+    networks:
+      - backend
+networks:
+  backend:
+    driver: bridge

+ 33 - 0
launch-admin/.gitignore

@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/

BIN
launch-admin/.mvn/wrapper/maven-wrapper.jar


+ 2 - 0
launch-admin/.mvn/wrapper/maven-wrapper.properties

@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar

+ 308 - 0
launch-admin/mvnw

@@ -0,0 +1,308 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#    https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Apache Maven Wrapper startup batch script, version 3.2.0
+#
+# Required ENV vars:
+# ------------------
+#   JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+#   MAVEN_OPTS - parameters passed to the Java VM when running Maven
+#     e.g. to debug Maven itself, use
+#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+  if [ -f /usr/local/etc/mavenrc ] ; then
+    . /usr/local/etc/mavenrc
+  fi
+
+  if [ -f /etc/mavenrc ] ; then
+    . /etc/mavenrc
+  fi
+
+  if [ -f "$HOME/.mavenrc" ] ; then
+    . "$HOME/.mavenrc"
+  fi
+
+fi
+
+# OS specific support.  $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "$(uname)" in
+  CYGWIN*) cygwin=true ;;
+  MINGW*) mingw=true;;
+  Darwin*) darwin=true
+    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
+    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
+    if [ -z "$JAVA_HOME" ]; then
+      if [ -x "/usr/libexec/java_home" ]; then
+        JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME
+      else
+        JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
+      fi
+    fi
+    ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+  if [ -r /etc/gentoo-release ] ; then
+    JAVA_HOME=$(java-config --jre-home)
+  fi
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
+fi
+
+# For Mingw, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+  [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] &&
+    JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)"
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+  javaExecutable="$(which javac)"
+  if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then
+    # readlink(1) is not available as standard on Solaris 10.
+    readLink=$(which readlink)
+    if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then
+      if $darwin ; then
+        javaHome="$(dirname "\"$javaExecutable\"")"
+        javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac"
+      else
+        javaExecutable="$(readlink -f "\"$javaExecutable\"")"
+      fi
+      javaHome="$(dirname "\"$javaExecutable\"")"
+      javaHome=$(expr "$javaHome" : '\(.*\)/bin')
+      JAVA_HOME="$javaHome"
+      export JAVA_HOME
+    fi
+  fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+  if [ -n "$JAVA_HOME"  ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+      # IBM's JDK on AIX uses strange locations for the executables
+      JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+      JAVACMD="$JAVA_HOME/bin/java"
+    fi
+  else
+    JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)"
+  fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+  echo "Error: JAVA_HOME is not defined correctly." >&2
+  echo "  We cannot execute $JAVACMD" >&2
+  exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+  echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+  if [ -z "$1" ]
+  then
+    echo "Path not specified to find_maven_basedir"
+    return 1
+  fi
+
+  basedir="$1"
+  wdir="$1"
+  while [ "$wdir" != '/' ] ; do
+    if [ -d "$wdir"/.mvn ] ; then
+      basedir=$wdir
+      break
+    fi
+    # workaround for JBEAP-8937 (on Solaris 10/Sparc)
+    if [ -d "${wdir}" ]; then
+      wdir=$(cd "$wdir/.." || exit 1; pwd)
+    fi
+    # end of workaround
+  done
+  printf '%s' "$(cd "$basedir" || exit 1; pwd)"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+  if [ -f "$1" ]; then
+    # Remove \r in case we run on Windows within Git Bash
+    # and check out the repository with auto CRLF management
+    # enabled. Otherwise, we may read lines that are delimited with
+    # \r\n and produce $'-Xarg\r' rather than -Xarg due to word
+    # splitting rules.
+    tr -s '\r\n' ' ' < "$1"
+  fi
+}
+
+log() {
+  if [ "$MVNW_VERBOSE" = true ]; then
+    printf '%s\n' "$1"
+  fi
+}
+
+BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
+if [ -z "$BASE_DIR" ]; then
+  exit 1;
+fi
+
+MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
+log "$MAVEN_PROJECTBASEDIR"
+
+##########################################################################################
+# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
+# This allows using the maven wrapper in projects that prohibit checking in binary data.
+##########################################################################################
+wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
+if [ -r "$wrapperJarPath" ]; then
+    log "Found $wrapperJarPath"
+else
+    log "Couldn't find $wrapperJarPath, downloading it ..."
+
+    if [ -n "$MVNW_REPOURL" ]; then
+      wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
+    else
+      wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
+    fi
+    while IFS="=" read -r key value; do
+      # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
+      safeValue=$(echo "$value" | tr -d '\r')
+      case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;;
+      esac
+    done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
+    log "Downloading from: $wrapperUrl"
+
+    if $cygwin; then
+      wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
+    fi
+
+    if command -v wget > /dev/null; then
+        log "Found wget ... using wget"
+        [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+        else
+            wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
+        fi
+    elif command -v curl > /dev/null; then
+        log "Found curl ... using curl"
+        [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
+        if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+            curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
+        else
+            curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
+        fi
+    else
+        log "Falling back to using Java to download"
+        javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
+        javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
+        # For Cygwin, switch paths to Windows format before running javac
+        if $cygwin; then
+          javaSource=$(cygpath --path --windows "$javaSource")
+          javaClass=$(cygpath --path --windows "$javaClass")
+        fi
+        if [ -e "$javaSource" ]; then
+            if [ ! -e "$javaClass" ]; then
+                log " - Compiling MavenWrapperDownloader.java ..."
+                ("$JAVA_HOME/bin/javac" "$javaSource")
+            fi
+            if [ -e "$javaClass" ]; then
+                log " - Running MavenWrapperDownloader.java ..."
+                ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
+            fi
+        fi
+    fi
+fi
+##########################################################################################
+# End of extension
+##########################################################################################
+
+# If specified, validate the SHA-256 sum of the Maven wrapper jar file
+wrapperSha256Sum=""
+while IFS="=" read -r key value; do
+  case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;
+  esac
+done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
+if [ -n "$wrapperSha256Sum" ]; then
+  wrapperSha256Result=false
+  if command -v sha256sum > /dev/null; then
+    if echo "$wrapperSha256Sum  $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then
+      wrapperSha256Result=true
+    fi
+  elif command -v shasum > /dev/null; then
+    if echo "$wrapperSha256Sum  $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then
+      wrapperSha256Result=true
+    fi
+  else
+    echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available."
+    echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties."
+    exit 1
+  fi
+  if [ $wrapperSha256Result = false ]; then
+    echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
+    echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
+    echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
+    exit 1
+  fi
+fi
+
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+  [ -n "$JAVA_HOME" ] &&
+    JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
+  [ -n "$CLASSPATH" ] &&
+    CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
+  [ -n "$MAVEN_PROJECTBASEDIR" ] &&
+    MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
+fi
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
+export MAVEN_CMD_LINE_ARGS
+
+WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+# shellcheck disable=SC2086 # safe args
+exec "$JAVACMD" \
+  $MAVEN_OPTS \
+  $MAVEN_DEBUG_OPTS \
+  -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
+  "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

+ 0 - 0
launch-admin/mvnw.cmd


+ 238 - 0
launch-admin/pom.xml

@@ -0,0 +1,238 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <!-- 关联父类-->
+    <parent>
+        <groupId>com.launch.webflux</groupId>
+        <artifactId>launch</artifactId>
+        <version>1.0.0</version>
+    </parent>
+
+
+    <artifactId>launch-admin</artifactId>
+
+    <description>Demo project for Spring Boot</description>
+
+    <packaging>jar</packaging>
+
+    <properties>
+
+        <!-- 工程构建过程中读取源码时使用的字符集 -->
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <java.version>21</java.version>
+        <spring-cloud.version>2023.0.0-RC1</spring-cloud.version>
+
+        <r2dbc-mysql>1.0.5</r2dbc-mysql>
+        <openapi.ui>2.2.0</openapi.ui>
+        <validation>3.2.0</validation>
+        <cola-component-dto>4.3.2</cola-component-dto>
+        <revision>2022.0.0.0</revision>
+        <redis.clients>5.0.2</redis.clients>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+
+        <!--        <dependency>-->
+        <!--            <groupId>redis.clients</groupId>-->
+        <!--            <artifactId>jedis</artifactId>-->
+        <!--            <version>2.9.0</version>-->
+        <!--        </dependency>-->
+
+        <!-- db -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-r2dbc</artifactId>
+        </dependency>
+
+        <!-- https://mvnrepository.com/artifact/io.asyncer/r2dbc-mysql -->
+        <dependency>
+            <groupId>io.asyncer</groupId>
+            <artifactId>r2dbc-mysql</artifactId>
+            <version>${r2dbc-mysql}</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.3.7</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.83</version>
+        </dependency>
+        <dependency>
+            <groupId>com.plumelog</groupId>
+            <artifactId>plumelog-logback</artifactId>
+            <version>3.4.2</version>
+        </dependency>
+
+        <!--单点登录 -->
+        <!--        <dependency>-->
+        <!--            <groupId>com.xuxueli</groupId>-->
+        <!--            <artifactId>xxl-sso-core</artifactId>-->
+        <!--            <version>1.1.1-SNAPSHOT</version>-->
+        <!--        </dependency>-->
+        <!--  r2dbc 连接池 -->
+        <dependency>
+            <groupId>io.r2dbc</groupId>
+            <artifactId>r2dbc-pool</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jdbc</artifactId>
+        </dependency>
+        <!--springdoc openapi swagger ui -->
+        <dependency>
+            <groupId>org.springdoc</groupId>
+            <artifactId>springdoc-openapi-starter-webflux-ui</artifactId>
+            <version>${openapi.ui}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springdoc</groupId>
+            <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
+            <version>${openapi.ui}</version>
+        </dependency>
+
+        <!--搭配校验使用-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+            <version>${validation}</version>
+        </dependency>
+        <!--让响应结果更美观 -->
+        <dependency>
+            <groupId>com.alibaba.cola</groupId>
+            <artifactId>cola-component-dto</artifactId>
+            <version>${cola-component-dto}</version>
+        </dependency>
+        <!--lombok -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <!--test -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <!--models-->
+        <dependency>
+            <groupId>com.launch.webflux</groupId>
+            <artifactId>launch-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.launch.webflux</groupId>
+            <artifactId>launch-r2dbc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.launch.webflux</groupId>
+            <artifactId>launch-redis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.launch.webflux</groupId>
+            <artifactId>launch-elasticsearch</artifactId>
+        </dependency>
+
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.github.shalousun</groupId>
+                <artifactId>smart-doc-maven-plugin</artifactId>
+                <version>2.3.1</version>
+                <!--建议用最新版本-->
+                <configuration>
+                    <!--指定生成文档的使用的配置文件,配置文件放在自己的项目中-->
+                    <configFile>./src/main/resources/smart-doc.json</configFile>
+                    <!--指定项目名称-->
+                    <projectName>SmartDoc-Demo</projectName>
+                    <!--smart-doc实现自动分析依赖树加载第三方依赖的源码,如果一些框架依赖库加载不到导致报错,这时请使用excludes排除掉-->
+                    <excludes>
+                        <!--格式为:groupId:artifactId;参考如下-->
+                        <!--1.0.7版本开始你还可以用正则匹配排除,如:poi.* -->
+                        <exclude>com.alibaba:fastjson</exclude>
+                    </excludes>
+                    <!--自1.0.8版本开始,插件提供includes支持-->
+                    <!--smart-doc能自动分析依赖树加载所有依赖源码,原则上会影响文档构建效率,因此你可以使用includes来让插件加载你配置的组件-->
+                    <includes>
+                        <!--格式为:groupId:artifactId;参考如下-->
+                        <include>com.launch.system.controller.tool.product</include>
+                    </includes>
+                </configuration>
+                <executions>
+                    <execution>
+                        <!--如果不需要在执行编译时启动smart-doc,则将phase注释掉-->
+                        <!--<phase>compile</phase>-->
+                        <goals>
+                            <!--smart-doc提供了html、openapi、markdown等goal,可按需配置-->
+                            <!--<goal>html</goal>-->
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.5.1</version>
+                <configuration>
+                    <source>21</source>
+                    <target>21</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>2.18.1</version>
+                <configuration>
+                    <skipTests>true</skipTests>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-deploy-plugin</artifactId>
+                <version>2.8.2</version>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+
+                <configuration>
+
+                    <jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
+                    <includeSystemScope>true</includeSystemScope>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <repositories>
+        <repository>
+            <id>spring-milestones</id>
+            <name>Spring Milestones</name>
+            <url>https://repo.spring.io/milestone</url>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </repository>
+    </repositories>
+
+</project>

+ 20 - 0
launch-admin/src/main/java/com/webflux/launchadmin/LaunchAdminApplication.java

@@ -0,0 +1,20 @@
+package com.webflux.launchadmin;
+
+
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+@EnableTransactionManagement
+@SpringBootApplication(scanBasePackages = "com.*")
+
+@EnableScheduling
+public class LaunchAdminApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(LaunchAdminApplication.class, args);
+    }
+
+}

+ 33 - 0
launch-admin/src/main/java/com/webflux/launchadmin/config/AuthenticationFilter.java

@@ -0,0 +1,33 @@
+package com.webflux.launchadmin.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.stereotype.Component;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.server.WebFilter;
+import org.springframework.web.server.WebFilterChain;
+import reactor.core.publisher.Mono;
+
+
+@Slf4j
+@Component
+public class AuthenticationFilter implements WebFilter {
+    @Override
+    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
+        ServerHttpRequest request = exchange.getRequest();
+        ServerHttpResponse response = exchange.getResponse();
+        response.getHeaders().add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, CorsConfiguration.ALL);
+        if (HttpMethod.OPTIONS.matches(request.getMethod().name())) {
+            response.getHeaders().add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, CorsConfiguration.ALL);
+            response.getHeaders().add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, CorsConfiguration.ALL);
+            response.setStatusCode(HttpStatus.OK);
+            return response.setComplete();
+        }
+		return chain.filter(exchange);
+    }
+}

+ 13 - 0
launch-admin/src/main/java/com/webflux/launchadmin/config/BaseConstants.java

@@ -0,0 +1,13 @@
+package com.webflux.launchadmin.config;
+
+/**
+ * @Description:
+ * @Author: launch
+ */
+public class BaseConstants {
+    public static String CONTEXT_KEY_USER_ID = "userId";
+    public static String CONTEXT_KEY_USER_NAME = "userName";
+    public static String CONTEXT_KEY_XXL_SSO_SESSION = "xxl_sso_session";
+    public static String CONTEXT_KEY_SYSCODE = "sysCode";
+    public static String CONTEXT_KEY_USERINFO = "userInfo";
+}

+ 79 - 0
launch-admin/src/main/java/com/webflux/launchadmin/config/BaseContextHandler.java

@@ -0,0 +1,79 @@
+package com.webflux.launchadmin.config;
+
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @Author: launch
+ */
+public class BaseContextHandler {
+    public static ThreadLocal<Map<String, Object>> threadLocal = new ThreadLocal<Map<String, Object>>();
+
+    public static void set(String key, Object value) {
+        Map<String, Object> map = threadLocal.get();
+        if (map == null) {
+            map = new HashMap<String, Object>();
+            threadLocal.set(map);
+        }
+        map.put(key, value);
+    }
+
+    public static Object get(String key) {
+        Map<String, Object> map = threadLocal.get();
+        if (map == null) {
+            map = new HashMap<String, Object>();
+            threadLocal.set(map);
+        }
+        return map.get(key);
+    }
+
+    public static String getUserId() {
+        Object value = get(BaseConstants.CONTEXT_KEY_USER_ID);
+        return returnObjectValue(value);
+    }
+
+    public static String getUserName() {
+        Object value = get(BaseConstants.CONTEXT_KEY_USER_NAME);
+        return returnObjectValue(value);
+    }
+
+    public static String getSessionId() {
+        Object value = get(BaseConstants.CONTEXT_KEY_XXL_SSO_SESSION);
+        return returnObjectValue(value);
+    }
+
+    public static Long getSysCode() {
+        Object value = get(BaseConstants.CONTEXT_KEY_SYSCODE);
+        return value == null ? null : (Long) value;
+    }
+
+
+
+    public static void setSessionId(String sessionId) {
+        set(BaseConstants.CONTEXT_KEY_XXL_SSO_SESSION, sessionId);
+    }
+
+    public static void setUserName(String userName) {
+        set(BaseConstants.CONTEXT_KEY_USER_NAME, userName);
+    }
+
+    public static void setUserId(String userID) {
+        set(BaseConstants.CONTEXT_KEY_USER_ID, userID);
+    }
+
+    public static void setSysCode(Long sysCode) {
+        set(BaseConstants.CONTEXT_KEY_SYSCODE, sysCode);
+    }
+
+
+    private static String returnObjectValue(Object value) {
+        return value == null ? null : value.toString();
+    }
+
+    public static void remove() {
+        threadLocal.remove();
+    }
+
+}

+ 220 - 0
launch-admin/src/main/java/com/webflux/launchadmin/config/LoginWebFiter.java

@@ -0,0 +1,220 @@
+package com.webflux.launchadmin.config;
+
+
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.webflux.launchadmin.context.UserContext;
+import com.webflux.launchadmin.context.XxlSsoUser;
+import com.webflux.launchcommon.utils.RL;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.data.redis.core.ReactiveRedisTemplate;
+import org.springframework.http.HttpCookie;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.server.RequestPath;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.http.server.reactive.ServerHttpResponse;
+import org.springframework.stereotype.Component;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.server.WebFilter;
+import org.springframework.web.server.WebFilterChain;
+import reactor.core.publisher.Mono;
+
+import java.io.IOException;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+@Component
+@Slf4j
+public class LoginWebFiter implements WebFilter {
+//    @Autowired
+//    private ReactiveRedisTemplate<String,Object> reactiveRedisTemplate;
+    @Value("${xxl.sso.excluded.paths}")
+    private String xxlSsoExcludedPaths;
+    @Value("${xxl.sso.excluded.start}")
+    private String xxlSsoExcludedstart;
+    @Value("${xxl.sso.server}")
+    private String loginPageUrl;
+    @SneakyThrows
+    @Override
+    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
+        ServerHttpRequest request = exchange.getRequest();
+        RequestPath path = request.getPath();
+        String string = path.toString();
+        String[] split = xxlSsoExcludedPaths.split(",");
+        String[] split1 = xxlSsoExcludedstart.split(",");
+        Optional<String> first = Stream.of(split).filter(string::equals).findFirst();
+        Optional<String> first1 = Stream.of(split1).filter(string::contains).findFirst();
+        if (first.isEmpty() && first1.isEmpty()) {
+            //验证权限
+           try {
+               String sessionid = getSessionid(exchange);
+               BaseContextHandler.setSessionId(sessionid);
+               Boolean user = getUser(getSessionid(exchange));
+
+
+               if (!user) {
+                   return notLogin(exchange);
+               }
+           }catch (Exception e){
+               //日志
+               log.error("LoginWebFiter getUserInfo E:"+ e.getMessage());
+           }
+        }
+        System.out.println("...abcd");
+        Mono<Void> filter = chain.filter(exchange); //放行
+        //流一旦经过某个操作就会变成新流
+        Mono<Void> voidMono = filter.doOnError(err -> {
+            System.out.println("目标方法异常以后...");
+        }) // 目标方法发生异常后做事
+                .doFinally(signalType -> {
+                    System.out.println("目标方法执行以后...");
+                });// 目标方法执行之后
+        //上面执行不花时间。
+        return voidMono; //看清楚返回的是谁!!!
+    }
+
+    private Mono<Void> notLogin(ServerWebExchange exchange) {
+        ServerHttpResponse response = exchange.getResponse();
+        response.setStatusCode( org.springframework.http.HttpStatus.NOT_IMPLEMENTED);
+        response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
+        RL result =new RL();
+        result.setCode(501);
+        result.setLoginPageUrl(loginPageUrl);
+        result.setMsg("sso not login.");
+        DataBuffer dataBuffer = response.bufferFactory().wrap(JSONUtil.toJsonStr(result).getBytes());
+        return response.writeWith(Mono.just(dataBuffer));
+    }
+
+    private static String  getSessionid(ServerWebExchange exchange) {
+        MultiValueMap<String, HttpCookie> cookies = exchange.getRequest().getCookies();
+        if (!cookies.containsKey("xxl_sso_sessionid")) {
+            return null;
+        }
+        String xxl_sso_sessionid = cookies.get("xxl_sso_sessionid").toString();
+        if (Objects.isNull(xxl_sso_sessionid)) {
+            return null;
+        }
+        return xxl_sso_sessionid.replace("[","").replace("]","");
+    }
+
+    public Boolean getUser(String cookie) throws IOException {
+        if (Objects.isNull(cookie)) {
+            log.error("111111111");
+            return false;
+        }
+        if(UserContext.cMap.containsKey(cookie)){
+            XxlSsoUser xxlSsoUser = UserContext.cMap.get(cookie);
+            BaseContextHandler.setUserId(xxlSsoUser.getUserid());
+            BaseContextHandler.setUserName(xxlSsoUser.getUsername());
+            return true;
+        }
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+        //https://kuaitou.mokamrp.com/api/system/qwlb/getAdminInfo
+        HttpGet httpget = new HttpGet("https://kuaitou.mokamrp.com/api/system/admin/getAdminInfo");
+        httpget.setHeader("Cookie",cookie);
+        CloseableHttpResponse response = httpclient.execute(httpget);
+        try {
+            HttpEntity entity = response.getEntity();
+            String result = EntityUtils.toString(entity);
+            EntityUtils.consume(entity);
+            log.error("3");
+            if (Objects.nonNull(result)) {
+                log.error("4");
+                JSONObject jsonObject = JSONUtil.parseObj(result);
+                if (jsonObject.containsKey("code") && jsonObject.get("code", Integer.class) == 200) {
+                    log.error("5");
+                    if(jsonObject.containsKey("data")){
+                        log.error("7");
+                        XxlSsoUser data = jsonObject.get("data", XxlSsoUser.class);
+                        BaseContextHandler.setUserId(data.getUserid());
+                        BaseContextHandler.setUserName(data.getUsername());
+                        UserContext.cMap.put(cookie,data);
+                        System.out.println(data);
+                        return true;
+                    }
+                }else if(jsonObject.containsKey("code") && jsonObject.get("code", Integer.class) == 501){
+                    return false;
+                }else {
+                    return true;
+                }
+            }
+            log.error("8");
+        } catch (Exception e) {
+            return true;
+        } finally {
+            response.close();
+        }
+        log.error("2222222222222");
+        return true;
+
+    }
+
+
+
+
+//    public static String parseStoreKey(String sessionId) {
+//        if (sessionId != null && sessionId.indexOf("_") > -1) {
+//            String[] sessionIdArr = sessionId.split("_");
+//            if (sessionIdArr.length == 2 && sessionIdArr[0] != null && sessionIdArr[0].trim().length() > 0) {
+//                String userId = sessionIdArr[0].trim();
+//                return userId;
+//            }
+//        }
+//
+//        return null;
+//    }
+//    private static String  xxl0(ServerWebExchange exchange) {
+//
+//        MultiValueMap<String, HttpCookie> cookies = exchange.getRequest().getCookies();
+//        if (!cookies.containsKey("xxl_sso_sessionid")) {
+//            return null;
+//        }
+//        String xxl_sso_sessionid = cookies.get("xxl_sso_sessionid").toString();
+//        if (Objects.isNull(xxl_sso_sessionid)) {
+//            return null;
+//        }
+//        String xxl_sso_sessionid1 = xxl_sso_sessionid.replace("[","");
+//        String xxl_sso_sessionid2 =xxl_sso_sessionid1.replace("]","");
+//
+//        String[] split = xxl_sso_sessionid2.split("=");
+//        if(Objects.isNull(split[1])){
+//            return null;
+//        }
+//        String value = split[1];
+//        String s = parseStoreKey(value);
+//        return redisKey(s);
+//    }
+//    private static String redisKey(String sessionId) {
+//        return "xxl_sso_sessionid".concat("#").concat(sessionId);
+//    }
+//
+//
+//
+//    public Boolean  xxl1(ServerWebExchange exchange){
+//        String key = xxl0(exchange);
+//        if (Objects.isNull(key)) {
+//            return false;
+//        }
+//        Mono<Object> objectMono = reactiveRedisTemplate.opsForValue().get(key);
+//    //    Optional<Object> o = objectMono.blockOptional();
+//        return false;
+//
+//    }
+//
+//    private Mono<Void> unauthorizedResponse(ServerWebExchange exchange, String msg) {
+//        return ServletUtils.webFluxResponseWriter(exchange.getResponse(), msg, HttpStatus.UNAUTHORIZED);
+//    }
+}

+ 25 - 0
launch-admin/src/main/java/com/webflux/launchadmin/config/MyWebConfiguration.java

@@ -0,0 +1,25 @@
+package com.webflux.launchadmin.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.reactive.config.CorsRegistry;
+import org.springframework.web.reactive.config.WebFluxConfigurer;
+
+@Configuration
+public class MyWebConfiguration {
+
+    //配置底层
+    @Bean
+    public WebFluxConfigurer webFluxConfigurer(){
+
+        return new WebFluxConfigurer() {
+            @Override
+            public void addCorsMappings(CorsRegistry registry) {
+                registry.addMapping("/**")
+                        .allowedHeaders("*")
+                        .allowedMethods("*")
+                        .allowedOrigins("localhost");
+            }
+        };
+    }
+}

+ 30 - 0
launch-admin/src/main/java/com/webflux/launchadmin/config/PlumeLogilterConfig.java

@@ -0,0 +1,30 @@
+package com.webflux.launchadmin.config;
+
+import com.webflux.launchadmin.filter.TraceIdFilter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.web.server.WebFilter;
+
+/**
+ * @author wangcheng
+ * @date 2024年07月16日 14:41
+ */
+@Order(Integer.MIN_VALUE)
+@Configuration
+public class PlumeLogilterConfig {
+
+    // @Bean
+    // public FilterRegistrationBean<WebFilter> filterRegistrationBean1() {
+    //     FilterRegistrationBean<WebFilter> filterRegistrationBean = new FilterRegistrationBean<>();
+    //     filterRegistrationBean.setFilter(initCustomFilter());
+    //     filterRegistrationBean.setUrlPatterns(Collections.singletonList("/*") );
+    //     filterRegistrationBean.setOrder(Integer.MIN_VALUE);
+    //     return filterRegistrationBean;
+    // }
+
+    @Bean
+    public WebFilter initCustomFilter() {
+        return new TraceIdFilter();
+    }
+}

+ 13 - 0
launch-admin/src/main/java/com/webflux/launchadmin/context/UserContext.java

@@ -0,0 +1,13 @@
+package com.webflux.launchadmin.context;
+
+
+
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.ConcurrentHashMap;
+@Component
+public  class UserContext {
+    public static ConcurrentHashMap<String, XxlSsoUser> cMap = new ConcurrentHashMap();
+
+
+}

+ 70 - 0
launch-admin/src/main/java/com/webflux/launchadmin/context/XxlSsoUser.java

@@ -0,0 +1,70 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by FernFlower decompiler)
+//
+
+package com.webflux.launchadmin.context;
+
+import java.io.Serializable;
+import java.util.Map;
+
+public class XxlSsoUser implements Serializable {
+    private static final long serialVersionUID = 42L;
+    private String userid;
+    private String username;
+    private Map<String, String> plugininfo;
+    private String version;
+    private int expireMinute;
+    private long expireFreshTime;
+
+    public XxlSsoUser() {
+    }
+
+    public String getUserid() {
+        return this.userid;
+    }
+
+    public void setUserid(String userid) {
+        this.userid = userid;
+    }
+
+    public String getUsername() {
+        return this.username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public Map<String, String> getPlugininfo() {
+        return this.plugininfo;
+    }
+
+    public void setPlugininfo(Map<String, String> plugininfo) {
+        this.plugininfo = plugininfo;
+    }
+
+    public String getVersion() {
+        return this.version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public int getExpireMinute() {
+        return this.expireMinute;
+    }
+
+    public void setExpireMinute(int expireMinute) {
+        this.expireMinute = expireMinute;
+    }
+
+    public long getExpireFreshTime() {
+        return this.expireFreshTime;
+    }
+
+    public void setExpireFreshTime(long expireFreshTime) {
+        this.expireFreshTime = expireFreshTime;
+    }
+}

+ 26 - 0
launch-admin/src/main/java/com/webflux/launchadmin/dispatcher/MailTask.java

@@ -0,0 +1,26 @@
+package com.webflux.launchadmin.dispatcher;
+
+import com.webflux.launchadmin.context.UserContext;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+@Component
+@Slf4j
+public class MailTask {
+
+
+
+	//@Scheduled(cron="0/30 * *  * * ? ")   //每600秒执行一次
+	public void handleTask(){
+    }
+
+    //清空用户Map数据 每天凌晨执行
+	@Scheduled(cron="1 1 0 * * ?")
+	public void clearUserContextMap(){
+		log.info("清空用户Map数据》》》》》》》》》》》》》》》》》》》》》》开始");
+		UserContext.cMap.clear();
+		log.info("清空用户Map数据》》》》》》》》》》》》》》》》》》》》》》 结束");
+	}
+}

+ 28 - 0
launch-admin/src/main/java/com/webflux/launchadmin/dispatcher/config/ScheduleConfig.java

@@ -0,0 +1,28 @@
+package com.webflux.launchadmin.dispatcher.config;
+ 
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
+ 
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+ 
+/**
+ * 没有此配置,则schedule为单线程串行执行
+ */
+@Configuration
+@EnableScheduling
+public class ScheduleConfig implements SchedulingConfigurer {
+ 
+    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
+        taskRegistrar.setScheduler(taskExecutor());
+    }
+ 
+    //配置线程池---触发器和任务共用的
+    @Bean()
+    public Executor taskExecutor() {
+        return Executors.newScheduledThreadPool(10);
+    }
+}

+ 33 - 0
launch-admin/src/main/java/com/webflux/launchadmin/filter/TraceIdFilter.java

@@ -0,0 +1,33 @@
+package com.webflux.launchadmin.filter;
+
+import com.plumelog.core.TraceId;
+import lombok.SneakyThrows;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.stereotype.Component;
+import org.springframework.web.server.ServerWebExchange;
+import org.springframework.web.server.WebFilter;
+import org.springframework.web.server.WebFilterChain;
+import reactor.core.publisher.Mono;
+
+/**
+ * @author wangcheng
+ * @date 2024年07月16日 14:48
+ */
+@Component
+public class TraceIdFilter implements WebFilter {
+    @SneakyThrows
+    @Override
+    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
+        try {
+            ServerHttpRequest request = exchange.getRequest();
+            String traceId = request.getQueryParams().getFirst("traceId");
+            if (traceId == null || traceId.isEmpty()) {
+                TraceId.set();
+            } else {
+                TraceId.logTraceID.set(traceId);
+            }
+        } finally {
+            return chain.filter(exchange);
+        }
+    }
+}

+ 88 - 0
launch-admin/src/main/java/com/webflux/launchadmin/global/BaseException.java

@@ -0,0 +1,88 @@
+package com.webflux.launchadmin.global;
+
+
+import org.springframework.util.StringUtils;
+
+/**
+ * 基础异常
+ * 
+ * @author launch
+ */
+public class BaseException extends RuntimeException
+{
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 所属模块
+     */
+    private String module;
+
+    /**
+     * 错误码
+     */
+    private String code;
+
+    /**
+     * 错误码对应的参数
+     */
+    private Object[] args;
+
+    /**
+     * 错误消息
+     */
+    private String defaultMessage;
+
+    public BaseException(String module, String code, Object[] args, String defaultMessage)
+    {
+        this.module = module;
+        this.code = code;
+        this.args = args;
+        this.defaultMessage = defaultMessage;
+
+    }
+
+    public BaseException(String module, String code, Object[] args)
+    {
+        this(module, code, args, null);
+    }
+
+    public BaseException(String module, String defaultMessage)
+    {
+        this(module, null, null, defaultMessage);
+    }
+
+    public BaseException(String code, Object[] args)
+    {
+        this(null, code, args, null);
+    }
+
+    public BaseException(String defaultMessage)
+    {
+        this(null, null, null, defaultMessage);
+    }
+
+    public String getModule()
+    {
+        return module;
+    }
+
+    public String getCode()
+    {
+        return code;
+    }
+
+    @Override
+    public String getMessage() {
+        return StringUtils.isEmpty(this.defaultMessage)?super.getMessage():this.defaultMessage;
+    }
+
+    public Object[] getArgs()
+    {
+        return args;
+    }
+
+    public String getDefaultMessage()
+    {
+        return defaultMessage;
+    }
+}

+ 24 - 0
launch-admin/src/main/java/com/webflux/launchadmin/global/GlobalExceptionHandler.java

@@ -0,0 +1,24 @@
+package com.webflux.launchadmin.global;
+
+import com.alibaba.cola.dto.Response;
+import com.webflux.launchcommon.returnObj.RStatus;
+import com.webflux.launchcommon.returnObj.RW;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import reactor.core.publisher.Mono;
+
+@RestControllerAdvice
+@Slf4j
+public class GlobalExceptionHandler {
+    @ResponseBody
+    @ResponseStatus(HttpStatus.BAD_REQUEST)
+    @ExceptionHandler(Exception.class)
+    public Mono<RW<Object>> handleException(Exception e) {
+        log.error(e.toString());
+        return RW.fail("500",e.getMessage(),Mono.just(e.getMessage()));
+    }
+}

+ 52 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/OutController.java

@@ -0,0 +1,52 @@
+package com.webflux.launchadmin.mysql.controller;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.webflux.launchadmin.global.BaseException;
+import com.webflux.launchadmin.mysql.controller.planNew.req.HfoRequest;
+import com.webflux.launchadmin.mysql.controller.planNew.req.HftRequest;
+import com.webflux.launchadmin.mysql.controller.planNew.req.KefuRequest;
+import com.webflux.launchadmin.mysql.controller.planNew.req.PlanCodeRequest;
+import com.webflux.launchadmin.mysql.controller.planNew.res.*;
+import com.webflux.launchadmin.mysql.entity.planNew.*;
+import com.webflux.launchadmin.mysql.service.planNew.goGenerate.GoGenerateService;
+import com.webflux.launchadmin.mysql.service.planNew.structure.GoRequest;
+import com.webflux.launchadmin.mysql.service.planNew.structure.Item;
+import com.webflux.launchcommon.returnObj.RStatus;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+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.web.bind.annotation.*;
+import reactor.core.publisher.Mono;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+
+/**
+ * 计划-H5
+ * @author lw12420
+ * @date 2024/05/21
+ */
+@RestController
+@RequestMapping("out")
+@Slf4j
+public class OutController {
+
+    @GetMapping("oauth")
+    public Mono<RStatus<String>> backgroupImageRes(){
+
+        return RStatus.success(Mono.just("成功"));
+    }
+
+}

+ 101 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/TempAllController/TempAll0Controller.java

@@ -0,0 +1,101 @@
+package com.webflux.launchadmin.mysql.controller.TempAllController;
+
+
+import com.webflux.launchadmin.mysql.entity.groupUsers.GroupUsers;
+import com.webflux.launchadmin.mysql.entity.takeaway.Takeaway;
+import com.webflux.launchadmin.mysql.entity.tempAll.TempAll;
+import com.webflux.launchadmin.mysql.entity.tempAll.dto.TempAllDtoInfo;
+import com.webflux.launchadmin.mysql.entity.tempAll.dto.TempAllDtoNext;
+import com.webflux.launchadmin.mysql.entity.tempAll.res.DeleteRes;
+import com.webflux.launchadmin.mysql.entity.tempAll.res.TempAllRsNext;
+import com.webflux.launchadmin.mysql.service.tempAll.TempAllServicesInterface;
+import com.webflux.launchcommon.returnObj.Paged;
+import com.webflux.launchcommon.returnObj.RStatus;
+import jakarta.annotation.Resource;
+import jakarta.validation.constraints.NotNull;
+import org.springframework.web.bind.annotation.*;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+/**
+ * @author lw12420
+ * @date 2024/07/17
+ */
+@RestController
+@RequestMapping("in/temp1")
+public class TempAll0Controller {
+    //Todo 直接复制 这是模版禁止修改
+    @Resource
+    private TempAllServicesInterface tempAllServicesInterface;
+
+
+    private static final Integer type=0;
+    /**
+     * 下拉
+     *
+     * @param name 默认值 ""
+     * @return {@link Mono}<{@link RStatus}<{@link Takeaway}>>
+     */
+    @GetMapping("getSltList")
+    public  Mono<RStatus<List<TempAllRsNext>>> getSelectList(@RequestParam("name") String name){
+        //Todo 不需要调整可以通用
+        return   tempAllServicesInterface.getSelectList(name,type);
+
+    }
+    /**
+     * 列表查询
+     * @param name 名称 默认空字符串
+     * @param page
+     * @param size
+     * @return {@link Mono}<{@link RStatus}<{@link Paged}<{@link GroupUsers}>>>
+     */
+    @GetMapping("page")
+    public Mono<RStatus<Paged<TempAllRsNext>>> page(@RequestParam("name") String name,
+                                                  @RequestParam("page")int page,
+                                                  @RequestParam("size")int size){
+        //FixMe 可能需要调整 jsonContent 内容
+        //  TempAllRsNext 替换
+        return tempAllServicesInterface.pageCommon(name, page, size,type);
+    }
+
+
+    /**
+     * 通过id删除 支持批量 案例:././deleteById/1,2,3
+     * @param id
+     * @return {@link Mono}<{@link RStatus}<{@link Long}>>
+     */
+    @DeleteMapping("deleteById/{id}")
+    public Mono<RStatus<DeleteRes<Long>>> deleteById(@PathVariable("id") @NotNull Long[]  id) {
+        // Todo 不需要调整
+        return  tempAllServicesInterface.deleteById(id);
+
+    }
+
+    /**
+     * 新增或修改 (groupUsersId校验是否有值)
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link GroupUsers}>>
+     */
+    @PostMapping("saveOrUpdate")
+    public Mono<RStatus<TempAll>> saveOrUpdate(@RequestBody TempAllDtoNext request) {
+        //FixMe 可能需要调整 jsonContent 内容
+        // TempAllDtoNext 替换
+        return  tempAllServicesInterface.saveOrUpdate(request,type);
+    }
+
+    /**
+     * 回显通过id查询
+     * @param id
+     * @return {@link Mono}<{@link RStatus}<{@link GroupUsers}>>
+     */
+    @GetMapping("getById/{id}")
+    public Mono<RStatus<TempAllDtoInfo>> getById(@PathVariable("id") @NotNull Long  id) {
+        //FixMe 可能需要调整 jsonContent 内容
+        // TempAllDtoInfo 替换
+        return  tempAllServicesInterface.getById(id);
+    }
+
+
+
+}

+ 101 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/TempAllController/TempAll1Controller.java

@@ -0,0 +1,101 @@
+package com.webflux.launchadmin.mysql.controller.TempAllController;
+
+
+import com.webflux.launchadmin.mysql.entity.groupUsers.GroupUsers;
+import com.webflux.launchadmin.mysql.entity.takeaway.Takeaway;
+import com.webflux.launchadmin.mysql.entity.tempAll.TempAll;
+import com.webflux.launchadmin.mysql.entity.tempAll.dto.TempAllDtoInfo;
+import com.webflux.launchadmin.mysql.entity.tempAll.dto.TempAllDtoNext;
+import com.webflux.launchadmin.mysql.entity.tempAll.dto.type1.TempAllDtoInfo1;
+import com.webflux.launchadmin.mysql.entity.tempAll.dto.type1.TempAllDtoNext1;
+import com.webflux.launchadmin.mysql.entity.tempAll.res.DeleteRes;
+import com.webflux.launchadmin.mysql.entity.tempAll.res.TempAllRsNext;
+import com.webflux.launchadmin.mysql.entity.tempAll.res.Type1.TempAllRsNext1;
+import com.webflux.launchadmin.mysql.service.tempAll.TempAllServicesInterface;
+import com.webflux.launchcommon.returnObj.Paged;
+import com.webflux.launchcommon.returnObj.RStatus;
+import jakarta.annotation.Resource;
+import jakarta.validation.constraints.NotNull;
+import org.springframework.web.bind.annotation.*;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+/**
+ * @author lw12420
+ * @date 2024/07/17
+ */
+@RestController
+@RequestMapping("in/temp")
+public class TempAll1Controller {
+    //Todo 直接复制 这是模版禁止修改
+    @Resource
+    private TempAllServicesInterface tempAllServicesInterface;
+
+
+    private static final Integer type=1; //Todo
+    /**
+     * 下拉
+     *
+     * @param name 默认值 ""
+     * @return {@link Mono}<{@link RStatus}<{@link Takeaway}>>
+     */
+    @GetMapping("getSltList")
+    public  Mono<RStatus<List<TempAllRsNext>>> getSelectList(@RequestParam("name") String name){
+        //Todo 不需要调整可以通用
+        return   tempAllServicesInterface.getSelectList(name,type);
+    }
+    /**
+     * 列表查询
+     * @param name 名称 默认空字符串
+     * @param page
+     * @param size
+     * @return {@link Mono}<{@link RStatus}<{@link Paged}<{@link GroupUsers}>>>
+     */
+    @GetMapping("page")
+    public Mono<RStatus<Paged<TempAllRsNext1>>> page(@RequestParam("name") String name,
+                                                     @RequestParam("page")int page,
+                                                     @RequestParam("size")int size){
+        //FixMe 可能需要调整 jsonContent 内容
+        //  TempAllRsNext 替换
+        return tempAllServicesInterface.pageCommon1(name, page, size,type);
+    }
+
+
+    /**
+     * 通过id删除 支持批量 案例:././deleteById/1,2,3
+     * @param id
+     * @return {@link Mono}<{@link RStatus}<{@link Long}>>
+     */
+    @DeleteMapping("deleteById/{id}")
+    public Mono<RStatus<DeleteRes<Long>>> deleteById(@PathVariable("id") @NotNull Long[]  id) {
+        // Todo 不需要调整
+        return  tempAllServicesInterface.deleteById(id);
+
+    }
+
+    /**
+     * 新增或修改 (groupUsersId校验是否有值)
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link GroupUsers}>>
+     */
+    @PostMapping("saveOrUpdate")
+    public Mono<RStatus<TempAll>> saveOrUpdate(@RequestBody TempAllDtoNext1 request) {
+        //FixMe 可能需要调整 jsonContent 内容
+        // TempAllDtoNext 替换
+        return  tempAllServicesInterface.saveOrUpdate1(request,type);
+    }
+
+    /**
+     * 回显通过id查询
+     * @param id
+     * @return {@link Mono}<{@link RStatus}<{@link GroupUsers}>>
+     */
+    @GetMapping("getById/{id}")
+    public Mono<RStatus<TempAllDtoInfo1>> getById(@PathVariable("id") @NotNull Long  id) {
+        //FixMe 可能需要调整 jsonContent 内容
+        // TempAllDtoInfo 替换
+        return  tempAllServicesInterface.getById1(id);
+    }
+
+}

+ 12 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/TempAllController/request/PageRequset.java

@@ -0,0 +1,12 @@
+package com.webflux.launchadmin.mysql.controller.TempAllController.request;
+
+import lombok.Data;
+@Data
+public class PageRequset {
+    /**
+     * 名称 默认空字符串
+     */
+    private String name;
+    private int page;
+    private int size;
+}

+ 75 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/groupUsers/GroupUsersController.java

@@ -0,0 +1,75 @@
+package com.webflux.launchadmin.mysql.controller.groupUsers;
+
+import com.webflux.launchadmin.mysql.controller.groupUsers.res.DeleteRes;
+import com.webflux.launchadmin.mysql.controller.groupUsers.res.GroupUsersRes;
+import com.webflux.launchadmin.mysql.entity.groupUsers.Dto.GroupUsersDto;
+import com.webflux.launchadmin.mysql.entity.groupUsers.GroupUsers;
+import com.webflux.launchadmin.mysql.service.groupUsers.GroupUsersServiceInterface;
+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.relational.core.query.Query;
+import org.springframework.web.bind.annotation.*;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+/**
+ * 群用户
+ * @author lw12420
+ * @date 2024/07/10
+ */
+@RestController
+@RequestMapping("in/groupUsers")
+public class GroupUsersController {
+
+    @Resource
+    private GroupUsersServiceInterface groupUsersServiceInterfave;
+
+    /**
+     * 列表查询
+     * @param type
+     * @param page
+     * @param size
+     * @return {@link Mono}<{@link RStatus}<{@link Paged}<{@link GroupUsers}>>>
+     */
+    @GetMapping("page")
+    public Mono<RStatus<Paged<GroupUsersRes>>> page(@RequestParam("type") Integer type,
+                                                 @RequestParam("page")int page,
+                                                 @RequestParam("size")int size){
+       return groupUsersServiceInterfave.page(type, page, size);
+    }
+
+
+    /**
+     * 通过id删除 支持批量 案例:././deleteById/1,2,3
+     * @param groupUsersId
+     * @return {@link Mono}<{@link RStatus}<{@link Long}>>
+     */
+    @DeleteMapping("deleteById/{groupUsersId}")
+    public Mono<RStatus<DeleteRes>> deletePosterById(@PathVariable("groupUsersId") @NotNull Long[]  groupUsersId) {
+        return  groupUsersServiceInterfave.deletePosterById(groupUsersId);
+
+    }
+
+    /**
+     * 新增或修改 (groupUsersId校验是否有值)
+     * @param groupUsersDto
+     * @return {@link Mono}<{@link RStatus}<{@link GroupUsers}>>
+     */
+    @PostMapping("saveOrUpdate")
+    public Mono<RStatus<GroupUsers>> saveOrUpdate(@RequestBody GroupUsersDto groupUsersDto) {
+        return  groupUsersServiceInterfave.saveOrUpdate(groupUsersDto);
+    }
+
+    /**
+     * 回显通过id查询
+     * @param groupUsersId
+     * @return {@link Mono}<{@link RStatus}<{@link GroupUsers}>>
+     */
+    @GetMapping("getById/{groupUsersId}")
+    public Mono<RStatus<GroupUsers>> getById(@PathVariable("groupUsersId") @NotNull Long  groupUsersId) {
+        return  groupUsersServiceInterfave.getById(groupUsersId);
+    }
+}

+ 12 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/groupUsers/res/DeleteRes.java

@@ -0,0 +1,12 @@
+package com.webflux.launchadmin.mysql.controller.groupUsers.res;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+public class DeleteRes<T> {
+    private List<T> Ids;
+}

+ 40 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/groupUsers/res/GroupUsersRes.java

@@ -0,0 +1,40 @@
+package com.webflux.launchadmin.mysql.controller.groupUsers.res;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.ZonedDateTime;
+
+@Data
+public class GroupUsersRes {
+    /**
+     * id 修改必填
+     */
+    private Long groupUsersId;//id
+    /**
+     * 头像
+     */
+    private  String groupUsersHead;
+    /**
+     * 昵称
+     */
+    private String groupUsersNickname;
+
+    /**
+     * 分類
+     */
+    private Integer groupUsersType;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private ZonedDateTime createdAt;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private ZonedDateTime updatedAt;
+
+
+    private String groupUsersName;
+
+    private  String createUser;
+
+    private   String createId;
+
+}

+ 219 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/lbIn/HomePageInController.java

@@ -0,0 +1,219 @@
+package com.webflux.launchadmin.mysql.controller.lbIn;
+
+import com.webflux.launchadmin.config.BaseContextHandler;
+import com.webflux.launchadmin.mysql.controller.lbIn.request.*;
+import com.webflux.launchadmin.mysql.entity.lb.HomePageTemp;
+import com.webflux.launchadmin.mysql.entity.lb.HomePageTempItem;
+import com.webflux.launchadmin.mysql.entity.test.Tweet;
+import com.webflux.launchadmin.mysql.repository.lb.HomePageTempItemRepository;
+import com.webflux.launchadmin.mysql.repository.lb.HomePageTempRepository;
+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.data.relational.core.query.Update;
+import org.springframework.data.relational.core.sql.SqlIdentifier;
+import org.springframework.web.bind.annotation.*;
+import reactor.core.publisher.Mono;
+
+import java.time.ZonedDateTime;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+
+/**
+ * 首页模版
+ * @author lw12420
+ * @date 2024/04/22
+ */
+@RestController
+@RequestMapping("/in/homePage")
+public class HomePageInController {
+
+    @Resource
+    private R2dbcEntityTemplate template;
+
+    @Resource
+    private HomePageTempRepository tempRepository;
+
+    @Resource
+    private HomePageTempItemRepository itemRepository;
+
+    /**
+     * 列表查询(首页模版)
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link Paged}<{@link HomePageTemp}>>>
+     */
+    @PostMapping("pageTemp")
+    public Mono<RStatus<Paged<HomePageTemp>>> page(@RequestBody HomePageRequest request)   {
+        Criteria criteria= Criteria.empty() ;
+        if (Objects.nonNull(request.getHomePageName()) && "" != request.getHomePageName()) {
+             criteria = criteria.and("home_page_name").is(request.getHomePageName());
+        }
+        if (Objects.nonNull(request.getTypeId()) && 0L != request.getTypeId()) {
+            criteria = criteria.and("type_id").is(request.getTypeId());
+        }
+        Query query = Query.query(criteria);
+        Criteria finalCriteria = criteria;
+        int skip  = (request.getPage() - 1) * request.getSize();
+        int limit = request.getPage() * request.getSize();
+        Mono<Paged<HomePageTemp>> pagedMono = template.count(query, HomePageTemp.class).flatMap(fm ->
+                template.select(Query.query(finalCriteria)
+                        .offset(skip)
+                        .limit(limit)
+                        .sort(Sort.by(Sort.Order.desc("create_time"))),HomePageTemp.class)
+                        .collectList()
+                        .map(list -> new Paged<>(fm, list,request.getPage(),request.getSize()))
+        );
+        return RStatus.successList(pagedMono);
+    }
+
+
+    /**
+     * 子页面列表查询(子页面)
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link Paged}<{@link HomePageTempItem}>>>
+     */
+    @PostMapping("pageTempItem")
+    public Mono<RStatus<Paged<HomePageTempItem>>> pageTempItem(@RequestBody HomePageItemRequest request)   {
+        Criteria criteria= Criteria.where("home_page_id").is(request.getHomePageId())
+                .and("item_type").is(request.getItemType()) ;
+        Query query = Query.query(criteria);
+        Criteria finalCriteria = criteria;
+        int skip  = (request.getPage() - 1) * request.getSize();
+        int limit = request.getPage() * request.getSize();
+        Mono<Paged<HomePageTempItem>> pagedMono = template.count(query, HomePageTempItem.class).flatMap(fm ->
+                template.select(Query.query(finalCriteria)
+                        .offset(skip)
+                        .limit(limit)
+                        .sort(Sort.by(Sort.Order.desc("create_time"))),HomePageTempItem.class)
+                        .collectList()
+                        .map(list -> new Paged<>(fm, list,request.getPage(),request.getSize()))
+        );
+        return RStatus.successList(pagedMono);
+    }
+
+    /**
+     * 保存(首页模版)
+     * @param saveRequest
+     * @return {@link Mono}<{@link RStatus}<{@link HomePageTemp}>>
+     */
+    @PostMapping("saveTemp")
+    public Mono<RStatus<HomePageTemp>> saveTemp(@RequestBody HomePageSaveRequest saveRequest){
+        HomePageTemp homePageTemp = new HomePageTemp(null,
+                saveRequest.getHomePageName(),
+                saveRequest.getTypeId(),
+                saveRequest.getTypeName(),
+                BaseContextHandler.getUserId(),
+                BaseContextHandler.getUserName(),
+                ZonedDateTime.now(),
+                ZonedDateTime.now());
+        Mono<HomePageTemp> insert = template.insert(homePageTemp);
+        return  RStatus.success(insert);
+    }
+
+    /**
+     * 子页面保存(子页面)
+     * @param saveRequest
+     * @return {@link Mono}<{@link RStatus}<{@link HomePageTempItem}>>
+     */
+    @PostMapping("saveTempItem")
+    public Mono<RStatus<HomePageTempItem>> saveTempItem(@RequestBody HomePageItemSaveRequest saveRequest){
+        HomePageTempItem homePageTempItem = new HomePageTempItem(null,
+                saveRequest.getHomePageId(),
+                BaseContextHandler.getUserId(),
+                BaseContextHandler.getUserName(),
+                ZonedDateTime.now(),
+                ZonedDateTime.now(),
+                saveRequest.getItemType(),
+                saveRequest.getTitle(),
+                saveRequest.getUrl(),
+                saveRequest.getUrlSize(),
+                saveRequest.getUrlWidth(),
+                saveRequest.getUrlHigh(),
+                saveRequest.getUrlMd5(),
+                saveRequest.getLink()
+              );
+        Mono<HomePageTempItem> insert = template.insert(homePageTempItem);
+        return  RStatus.success(insert);
+    }
+
+    /**
+     * 修改(首页模版)
+     * @param saveRequest
+     * @return {@link Mono}<{@link RStatus}<{@link HomePageTemp}>>
+     */
+    @PostMapping("updateTemp")
+    public Mono<RStatus<Long>> update(@RequestBody HomePageUpdateRequest saveRequest){
+        Criteria empty = Criteria.where("home_page_id").is(saveRequest.getHomePageId());
+        HashMap<SqlIdentifier, Object> sqlIdentifierObjectHashMap = new HashMap<>();
+        sqlIdentifierObjectHashMap.put(SqlIdentifier.quoted("update_time"),ZonedDateTime.now());
+
+        if(Objects.nonNull(saveRequest.getHomePageName()) && !"".equals(saveRequest.getHomePageName())){
+            sqlIdentifierObjectHashMap.put(SqlIdentifier.quoted("home_page_name"),saveRequest.getHomePageName());
+        }
+        if(Objects.nonNull(saveRequest.getTypeName()) && !"".equals(saveRequest.getTypeName())){
+            sqlIdentifierObjectHashMap.put(SqlIdentifier.quoted("type_name"),saveRequest.getTypeName());
+        }
+        if(Objects.nonNull(saveRequest.getTypeId()) && 0L!=saveRequest.getTypeId()){
+            sqlIdentifierObjectHashMap.put(SqlIdentifier.quoted("type_id"),saveRequest.getTypeId());
+        }
+        Mono<Long> update1 = template.update(Query.query(empty), Update.from(sqlIdentifierObjectHashMap), HomePageTemp.class);
+        return  RStatus.success(update1);
+    }
+
+    /**
+     * 子页面修改(子页面)
+     * @param saveRequest
+     * @return {@link Mono}<{@link RStatus}<{@link Long}>>
+     */
+    @PostMapping("updateTempItem")
+    public Mono<RStatus<Long>> updateTempItem(@RequestBody HomePageItemUpdateRequest saveRequest){
+        Criteria empty = Criteria.where("home_page_item_id").is(saveRequest.getHomePageItemId());
+        Map<SqlIdentifier, Object> assignments = new HashMap<>();
+        assignments.put(SqlIdentifier.quoted("update_time"),ZonedDateTime.now());
+        if(Objects.nonNull(saveRequest.getTitle()) && !"".equals(saveRequest.getTitle())){
+            assignments.put(SqlIdentifier.quoted("title"),saveRequest.getTitle());
+        }
+        if(Objects.nonNull(saveRequest.getLink()) && !"".equals(saveRequest.getLink())){
+            assignments.put(SqlIdentifier.quoted("link"),saveRequest.getLink());
+        }
+        if(Objects.nonNull(saveRequest.getUrl()) && !"".equals(saveRequest.getUrl())){
+            assignments.put(SqlIdentifier.quoted("url"),saveRequest.getUrl());
+            assignments.put(SqlIdentifier.quoted("url_md5"),saveRequest.getUrlMd5());
+            assignments.put(SqlIdentifier.quoted("url_width"),saveRequest.getUrlWidth());
+            assignments.put(SqlIdentifier.quoted("url_high"),saveRequest.getUrlHigh());
+        }
+        Update from = Update.from(assignments);
+        Mono<Long> update1 = template.update(Query.query(empty), from, HomePageTempItem.class);
+        return  RStatus.success(update1);
+    }
+
+    /**
+     * 子页面delete(子页面)
+     * @param homePageItemId
+     * @return {@link Mono}<{@link RStatus}<{@link Void}>>
+     */
+    @DeleteMapping("deleteItemById/{homePageItemId}")
+    public Mono<RStatus<Long>> deleteItemById (@PathVariable("homePageItemId")  @NotNull  Long homePageItemId){
+        Mono<Long> home_page_item_id = template.delete(Query.query(Criteria.where("home_page_item_id").is(homePageItemId)), HomePageTempItem.class);
+        return RStatus.success(home_page_item_id);
+    }
+
+    /**
+     * 首页面delete
+     * @param homePageId
+     * @return {@link Mono}<{@link RStatus}<{@link Void}>>
+     */
+    @DeleteMapping("deleteTempById/{homePageId}")
+    public Mono<RStatus<Long>> deleteTempById (@PathVariable("homePageId")  @NotNull  Long homePageId){
+        Mono<Long> home_page_id = template.delete(Query.query(Criteria.where("home_page_id").is(homePageId)), HomePageTemp.class);
+        return RStatus.success(home_page_id);
+    }
+
+}

+ 19 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/lbIn/request/HomePageItemRequest.java

@@ -0,0 +1,19 @@
+package com.webflux.launchadmin.mysql.controller.lbIn.request;
+
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Data
+public class HomePageItemRequest {
+
+    private Integer page;
+    private Integer size;
+    @NotNull
+    private Long homePageId;
+    /**
+     * Banner:b 推荐:t 热门:r
+     */
+    @NotEmpty
+    private  String itemType;
+}

+ 45 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/lbIn/request/HomePageItemSaveRequest.java

@@ -0,0 +1,45 @@
+package com.webflux.launchadmin.mysql.controller.lbIn.request;
+
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Data
+public class HomePageItemSaveRequest {
+    @NotNull
+    private Long homePageId;
+    /**
+     * Banner:b 推荐:t 热门:r
+     */
+    @NotNull
+    private String itemType;
+    /**
+     * 标题
+     */
+    private  String title;
+    /**
+     * 封面url
+     */
+    private String url;
+    /**
+     * 选填
+     */
+    private  Long urlSize;
+    /**
+     * 选填
+     */
+    private Long urlWidth;
+    /**
+     * 选填
+     */
+    private Long urlHigh;
+    /**
+     * 选填
+     */
+    private String urlMd5;
+
+    /**
+     * 链接
+     */
+    private String link;
+}

+ 47 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/lbIn/request/HomePageItemUpdateRequest.java

@@ -0,0 +1,47 @@
+package com.webflux.launchadmin.mysql.controller.lbIn.request;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Data
+public class HomePageItemUpdateRequest {
+
+    @NotNull
+    private Long  homePageItemId;
+    @NotNull
+    private Long homePageId;
+    /**
+     * Banner:b 推荐:t 热门:r
+     */
+//    @NotNull
+//    private String itmeType;
+    /**
+     * 标题
+     */
+    private  String title;
+    /**
+     * url
+     */
+    private String url;
+    /**
+     * 选填
+     */
+    private  Long urlSize;
+    /**
+     * 选填
+     */
+    private Long urlWidth;
+    /**
+     * 选填
+     */
+    private Long urlHigh;
+    /**
+     * 选填
+     */
+    private String urlMd5;
+    /**
+     * 链接
+     */
+
+    private String link;
+}

+ 13 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/lbIn/request/HomePageRequest.java

@@ -0,0 +1,13 @@
+package com.webflux.launchadmin.mysql.controller.lbIn.request;
+
+import io.r2dbc.spi.Parameter;
+import lombok.Data;
+
+@Data
+public class HomePageRequest {
+
+    private Integer page;
+    private Integer size;
+    private String homePageName;
+    private Long typeId;
+}

+ 25 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/lbIn/request/HomePageSaveRequest.java

@@ -0,0 +1,25 @@
+package com.webflux.launchadmin.mysql.controller.lbIn.request;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Data
+public class HomePageSaveRequest {
+
+    /**
+     *名称
+     */
+    @NotNull
+    private   String homePageName;
+    /**
+     * 类型 id
+     */
+    @NotNull
+    private Long typeId;
+    /**
+     * 类型 name
+     */
+    @NotNull
+    private String typeName;
+
+}

+ 29 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/lbIn/request/HomePageUpdateRequest.java

@@ -0,0 +1,29 @@
+package com.webflux.launchadmin.mysql.controller.lbIn.request;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Data
+public class HomePageUpdateRequest {
+    /**
+     * 修改必填
+     */
+    @NotNull
+    private Long homePageId;
+    /**
+     *名称
+     */
+    @NotNull
+    private   String homePageName;
+    /**
+     * 类型 id
+     */
+    @NotNull
+    private Long typeId;
+    /**
+     * 类型 name
+     */
+    @NotNull
+    private String typeName;
+
+}

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

@@ -0,0 +1,139 @@
+package com.webflux.launchadmin.mysql.controller.lbOut;
+
+import com.webflux.launchadmin.global.BaseException;
+import com.webflux.launchadmin.mysql.controller.lbIn.request.HomePageItemRequest;
+import com.webflux.launchadmin.mysql.controller.lbOut.request.HomePageItemOutRequest;
+import com.webflux.launchadmin.mysql.controller.lbOut.resp.DataList;
+import com.webflux.launchadmin.mysql.entity.lb.HomePageTemp;
+import com.webflux.launchadmin.mysql.entity.lb.HomePageTempItem;
+import com.webflux.launchadmin.mysql.entity.lb.Plan;
+import com.webflux.launchadmin.mysql.repository.lb.HomePageTempItemRepository;
+import com.webflux.launchadmin.mysql.repository.lb.HomePageTempRepository;
+import com.webflux.launchcommon.returnObj.RStatus;
+import jakarta.annotation.Resource;
+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.Mono;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+
+/**
+ * 首页模版
+ * @author lw12420
+ * @date 2024/04/22
+ */
+@RestController
+@RequestMapping("/out/homePage")
+public class HomePageOutController {
+
+
+    @Resource
+    private R2dbcEntityTemplate template;
+
+    @Resource
+    private HomePageTempRepository tempRepository;
+
+    @Resource
+    private HomePageTempItemRepository itemRepository;
+
+
+    @GetMapping("test")
+    public Mono<RStatus<String>> test(){
+        Mono<String> cc = Mono.just("链接成功");
+        return RStatus.success(cc);
+    }
+
+    @PostMapping("pageTempItem1")
+    public Mono<RStatus<List<HomePageTemp>>> pageTempItem1(@RequestBody HomePageItemOutRequest request)   {
+        String code = request.getCode();
+        Mono<List<HomePageTemp>> type_id = template.select(Query.query(Criteria.where("type_id").is(4)), HomePageTemp.class).collectList();
+        // Mono<Plan> code1 = template.selectOne(Query.query(Criteria.where("code").is(code)), Plan.class);
+        return RStatus.success(type_id);
+    }
+
+    
+    /**
+     * H5 短剧查询
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link DataList}<{@link HomePageTempItem}>>>
+     */
+    @PostMapping("pageTempItem")
+    public Mono<RStatus<DataList<HomePageTempItem>>> pageTempItem(@RequestBody HomePageItemOutRequest request)   {
+        String code = request.getCode();
+        Mono<Plan> code1 = template.selectOne(Query.query(Criteria.where("code").is(code)), Plan.class);
+        code1.switchIfEmpty(Mono.error(new BaseException("code is match failed")));
+        Mono<DataList<HomePageTempItem>> dataListMono = code1.filter(f->Objects.nonNull(f.groupTypeIdSc())&& f.groupTypeIdSc()>0).flatMap(plan ->
+                template.select(Query.query(Criteria.where("type_id").is(plan.groupTypeIdSc())), HomePageTemp.class)
+                        .collectList()
+                        .filter(f->!f.isEmpty())
+                .flatMap(fm -> Mono.just(selectRandomDataOne(fm)))
+                .flatMap(homePageTemp -> template.select(Query.query(Criteria.where("home_page_id").is(homePageTemp.homePageId())), HomePageTempItem.class)
+                        .collectList()
+                        .map(mp -> {
+                    Map<String, List<HomePageTempItem>> collect = mp.stream().collect(Collectors.groupingBy(HomePageTempItem::itemType));
+                    Integer bannerSize = request.getBannerSize();
+                    Integer hotSize = request.getHotSize();
+                    Integer recommendSize = request.getRecommendSize();
+                    List<HomePageTempItem> bannerList = new ArrayList<>();
+                    List<HomePageTempItem> hotList = new ArrayList<>();
+                    List<HomePageTempItem> recommendList = new ArrayList<>();
+                    collect.forEach((k, v) -> {
+                        if ("b".equals(k.trim())) {
+                            if (v.size() <= bannerSize || bannerSize == 0) {
+                                bannerList.addAll(v);
+                            } else {
+                                bannerList.addAll(selectRandomData(v, bannerSize));
+                            }
+                        } else if ("r".equals(k.trim())) {
+                            if (v.size() <= hotSize || hotSize == 0) {
+                                hotList.addAll(v);
+                            } else {
+                                hotList.addAll(selectRandomData(v, hotSize));
+                            }
+                        } else if ("t".equals(k.trim())) {
+                            if (v.size() <= recommendSize || recommendSize == 0) {
+                                recommendList.addAll(v);
+                            } else {
+                                recommendList.addAll(selectRandomData(v, recommendSize));
+                            }
+                        }
+                    });
+                    return new DataList<HomePageTempItem>("成功",bannerList, hotList, recommendList);
+                }).switchIfEmpty(Mono.error(new BaseException(" 首页模版查询结果无关联子模版")))
+                ).switchIfEmpty(Mono.error(new BaseException(" 根据模版类型匹配结果为空"))))
+                .switchIfEmpty(Mono.error(new BaseException(" 通过code查询结果为空")))
+                .onErrorResume(throwable ->Mono.just(new DataList<HomePageTempItem>(throwable.getMessage(),List.of(), List.of(), List.of())) );
+        return RStatus.successList(dataListMono);
+    }
+
+    public static <T> List<T> selectRandomData(List<T> dataList, int count) {
+        List<T> selectedData = new ArrayList<>();
+        Random random = new Random();
+
+        while (selectedData.size() < count) {
+            int randomIndex = random.nextInt(dataList.size());
+            T data = dataList.get(randomIndex);
+
+            if (!selectedData.contains(data)) {
+                selectedData.add(data);
+            }
+        }
+        return selectedData;
+    }
+
+    public static <T> T selectRandomDataOne(List<T> dataList) {
+        Random random = new Random();
+        int randomIndex = random.nextInt(dataList.size());
+        T data = dataList.get(randomIndex);
+        return data;
+    }
+
+}

+ 31 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/lbOut/request/HomePageItemOutRequest.java

@@ -0,0 +1,31 @@
+package com.webflux.launchadmin.mysql.controller.lbOut.request;
+
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Data
+public class HomePageItemOutRequest {
+
+    /**
+     * 全部:0 ;其他数值对应数量
+     */
+    @NotNull
+    private Integer bannerSize;
+    /**
+     * 全部:0 ;其他数值对应数量
+     */
+    @NotNull
+    private Integer hotSize;
+
+    /**
+     * 全部:0 ;其他数值对应数量recommend
+     */
+    @NotNull
+    private Integer recommendSize;
+
+
+    @NotNull
+    private String code;
+
+}

+ 10 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/lbOut/resp/DataList.java

@@ -0,0 +1,10 @@
+package com.webflux.launchadmin.mysql.controller.lbOut.resp;
+
+import java.util.List;
+
+public record DataList<T>(
+        String message,
+        List<T> bannerlists,
+        List<T> hotLists,
+        List<T> recommendLists) {
+}

+ 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;
+
+}

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

@@ -0,0 +1,14 @@
+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;
+    private  String listButton;
+
+}

+ 29 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/otherServices/OtherServicesController.java

@@ -0,0 +1,29 @@
+package com.webflux.launchadmin.mysql.controller.otherServices;
+
+import com.webflux.launchadmin.mysql.controller.otherServices.res.ByCodeGetImportDomainRes;
+import com.webflux.launchadmin.mysql.controller.planNew.res.PlanNewAllRs;
+import com.webflux.launchadmin.mysql.service.otherServices.OtherServicesInterface;
+import com.webflux.launchcommon.returnObj.RStatus;
+import jakarta.annotation.Resource;
+import jakarta.validation.constraints.NotNull;
+import org.springframework.web.bind.annotation.*;
+import reactor.core.publisher.Mono;
+
+@RestController
+@RequestMapping("out/otherServices")
+public class OtherServicesController {
+
+    @Resource
+    private OtherServicesInterface otherServicesInterface;
+
+    /**
+     * 【ID1015681】
+     * 入口链接对外接口
+     * @param code
+     * @return {@link Mono}<{@link RStatus}<{@link PlanNewAllRs}>>
+     */
+    @GetMapping("byCodeGetImportDomain")
+    public Mono<RStatus<ByCodeGetImportDomainRes>> byCodeGetImportDomain(@RequestParam("code")  @NotNull String code){
+        return otherServicesInterface.byCodeGetImportDomain(code);
+    }
+}

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

@@ -0,0 +1,8 @@
+package com.webflux.launchadmin.mysql.controller.otherServices.res;
+
+import lombok.Data;
+
+@Data
+public class ByCodeGetImportDomainRes {
+    String domain;
+}

+ 331 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/PlanNewCommonController.java

@@ -0,0 +1,331 @@
+package com.webflux.launchadmin.mysql.controller.planNew;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.StrUtil;
+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.planNew.req.PlanReq;
+import com.webflux.launchadmin.mysql.controller.planNew.req.ServiceGroupSettingItemRequest;
+import com.webflux.launchadmin.mysql.controller.planNew.res.PlanNewAllRs;
+import com.webflux.launchadmin.mysql.entity.planNew.PlanNew;
+import com.webflux.launchadmin.mysql.entity.planNew.PlanNewBackgroupPoster;
+import com.webflux.launchadmin.mysql.entity.planNew.PlanNewCommon;
+import com.webflux.launchadmin.mysql.entity.planNew.Poster;
+import com.webflux.launchadmin.mysql.service.planNew.goGenerate.GoGenerateService;
+import com.webflux.launchadmin.mysql.service.planNew.structure.GoRequest;
+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.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+
+/**
+ * 裂变计划通用配置列表
+ * @date 2024/07/10
+ */
+@RestController
+@RequestMapping("in/planNewCommon")
+public class PlanNewCommonController {
+    @Resource
+    private R2dbcEntityTemplate template;
+
+    @Resource
+    private GoGenerateService goGenerateService;
+
+
+    /**
+     * 保存计划
+     * @param saveRequest
+     * @return {@link Mono}<{@link RStatus}<{@link String}>>
+     */
+    @PostMapping("savePlan")
+    public Mono<RStatus<String>> savePlan(@RequestBody PlanReq saveRequest) {
+
+            if (StrUtil.isBlank(saveRequest.getPlanNewId())) {
+                // 新增
+                return this.savePlanCommon(saveRequest);
+            } else {
+                // 编辑
+                return this.updatePlanCommon(saveRequest);
+            }
+    }
+
+    /**
+     * 新增计划
+     *
+     * @param saveRequest
+     * @return {@link Mono}<{@link RStatus}<{@link String}>>
+     */
+    private Mono<RStatus<String>> savePlanCommon(PlanReq saveRequest) {
+        String userName = BaseContextHandler.getUserName();
+        String userId = BaseContextHandler.getUserId();
+        saveRequest.setCode(IdUtil.fastSimpleUUID());
+        Mono<String> previewUrl = this.getPreviewUrl(saveRequest);
+        Mono<PlanNewCommon> insert = previewUrl.flatMap(f -> {
+            PlanNewCommon plan = new PlanNewCommon(
+                    IdUtil.fastSimpleUUID(),
+                    saveRequest.getName(),
+                    saveRequest.getCode(),
+                    saveRequest.getType(),
+                    saveRequest.getGroupId(),
+                    saveRequest.getPosterTemplateId(),
+                    saveRequest.getImportDomain(),
+                    f,
+                    saveRequest.getConfigJson(),
+                    userName,
+                    userId,
+                    userName,
+                    userId,
+                    ZonedDateTime.now(),
+                    ZonedDateTime.now()
+            );
+            return template.insert(plan);
+        });
+        Mono<String> map = insert.flatMap(f -> {
+            Flux<PlanNewBackgroupPoster> just = this.getPlanNewBackGroupPosterFlux(saveRequest, f);
+            return Mono.zip(this.batchInsert(just), Mono.just(f)).flatMap(ff -> {
+                PlanNewCommon t2 = ff.getT2();
+                return Mono.just(t2.id());
+            });
+        });
+        return RStatus.success(map);
+    }
+
+    /**
+     * 编辑计划
+     */
+    private Mono<RStatus<String>> updatePlanCommon(PlanReq updateRequest) {
+        String userName = BaseContextHandler.getUserName();
+        String userId = BaseContextHandler.getUserId();
+        Mono<PlanNewCommon> planNewCommonMono = template.selectOne(Query.query(Criteria.where("id").is(updateRequest.getPlanNewId())), PlanNewCommon.class);
+        Mono<String> previewUrl = this.getPreviewUrl(updateRequest);
+        Mono<PlanNewCommon> updateMono = Mono.zip(previewUrl, planNewCommonMono).flatMap(f -> {
+            PlanNewCommon old = f.getT2();
+            PlanNewCommon plan = new PlanNewCommon(
+                    old.id(),
+                    updateRequest.getName(),
+                    old.code(),
+                    updateRequest.getType(),
+                    updateRequest.getGroupId(),
+                    updateRequest.getPosterTemplateId(),
+                    updateRequest.getImportDomain(),
+                    f.getT1(),
+                    updateRequest.getConfigJson(),
+                    old.createUser(),
+                    old.createId(),
+                    userName,
+                    userId,
+                    old.createdAt(),
+                    ZonedDateTime.now()
+            );
+            return Mono.just(plan);
+        }).flatMap(template::update);
+        Mono<String> map = updateMono.flatMap(f1 -> {
+            Mono<Long> ml = template.delete(Query.query(Criteria.where("plan_new_id").is(f1.id())), PlanNewBackgroupPoster.class);
+            return Mono.zip(Mono.just(f1), ml).flatMap(ff -> Mono.just(f1));
+        }).flatMap(f -> {
+            Flux<PlanNewBackgroupPoster> just = this.getPlanNewBackGroupPosterFlux(updateRequest, f);
+            return Mono.zip(this.batchInsert(just), Mono.just(f)).flatMap(ff -> {
+                PlanNewCommon t2 = ff.getT2();
+                return Mono.just(t2.id());
+            });
+        });
+        return RStatus.success(map);
+    }
+
+    /**
+     * 生成预览url
+     */
+    private Mono<String> getPreviewUrl(PlanReq planReq) {
+        return template
+                .select(Query.query(Criteria.where("poster_template_id").is(planReq.getPosterTemplateId()))
+                        .sort(Sort.by(Sort.Order.asc("created_at"))), Poster.class)
+                .switchIfEmpty(Mono.error(new BaseException("未查询到海报模版")))
+                .onErrorResume(throwable -> Mono.error(new Exception("未查询到海报模版")))
+                .collectList().flatMap(f -> {
+                    Poster poster = f.getFirst();
+                    String posterTemplate = poster.posterTemplate();
+                    JSONObject jsonObject = JSONUtil.parseObj(posterTemplate);
+                    GoRequest goRequest = new GoRequest();
+                    BeanUtil.copyProperties(jsonObject, goRequest);
+                    ServiceGroupSettingItemRequest serviceGroupSettingItemRequest = planReq.getBackgroupFxSetting().getFirst();
+                    return goGenerateService.saveAndUpdatePlanGenerateImage0(goRequest,
+                            goGenerateService.setCusqrcodeSetV(goRequest),// getStringBuilderMono(goRequest),
+                            serviceGroupSettingItemRequest,
+                            planReq);
+                });
+    }
+
+    private Flux<PlanNewBackgroupPoster> getPlanNewBackGroupPosterFlux(PlanReq saveRequest, PlanNewCommon f) {
+        ArrayList<PlanNewBackgroupPoster> listeningPlanNewBackGroupPosters = new ArrayList<>();
+        List<ServiceGroupSettingItemRequest> backGroupFxSetting = saveRequest.getBackgroupFxSetting();
+        backGroupFxSetting.forEach(fx -> {
+            PlanNewBackgroupPoster listeningPlanNewBackgroupPoster = fxBackGroupSettingsSave(fx, f.id(), 1);
+            listeningPlanNewBackGroupPosters.add(listeningPlanNewBackgroupPoster);
+        });
+        if (CollUtil.isNotEmpty(saveRequest.getBackgroupQsSetting())) {
+            List<ServiceGroupSettingItemRequest> backGroupQsSetting = saveRequest.getBackgroupQsSetting();
+            backGroupQsSetting.forEach(fx -> {
+                PlanNewBackgroupPoster listeningPlanNewBackGroupPoster = fxBackGroupSettingsSave(fx, f.id(), 2);
+                listeningPlanNewBackGroupPosters.add(listeningPlanNewBackGroupPoster);
+            });
+        }
+        return Flux.fromIterable(listeningPlanNewBackGroupPosters);
+    }
+
+    private PlanNewBackgroupPoster fxBackGroupSettingsSave(ServiceGroupSettingItemRequest request, String planNewId, Integer qsOrFx) {
+        return new PlanNewBackgroupPoster(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);
+
+    }
+
+    private Mono<List<PlanNewBackgroupPoster>> batchInsert(Flux<PlanNewBackgroupPoster> entities) {
+        return entities.flatMap(entity -> template
+                .insert(PlanNewBackgroupPoster.class).using(entity)).collectList();
+    }
+
+
+    /**
+     * 获取计划详情
+     * @param type
+     * @param planId
+     * @return {@link Mono}<{@link RStatus}<{@link PlanNewCommon}>>
+     */
+    @GetMapping("getPlanInfo/{type}/{planId}")
+    public Mono<RStatus<PlanNewCommon>> planNewInfo(@PathVariable("type") @NotNull Integer type, @PathVariable("planId") @NotNull String planId) {
+
+            // 交友计划
+            Mono<PlanNewCommon> planNewCommonMono = template.selectOne(Query.query(Criteria.where("id").is(planId)), PlanNewCommon.class)
+                    .switchIfEmpty(Mono.error(new BaseException("计划id异常")))
+                    .onErrorResume(throwable -> Mono.error(new Exception("计划id异常")));
+            return RStatus.success(planNewCommonMono);
+
+    }
+
+
+    /**
+     * 复制计划
+     * @param type
+     * @param planId
+     * @return {@link Mono}<{@link RStatus}<{@link String}>>
+     */
+    @GetMapping("copyById/{type}/{planId}")
+    public Mono<RStatus<String>> copyById(@PathVariable("type") @NotNull Integer type, @PathVariable("planId") @NotNull String planId) {
+
+            // 交友计划
+            String userName = BaseContextHandler.getUserName();
+            String userId = BaseContextHandler.getUserId();
+            Mono<PlanNewCommon> planNewCommonMono = template.selectOne(Query.query(Criteria.where("id").is(planId)), PlanNewCommon.class)
+                    .flatMap(f -> {
+                        PlanNewCommon planNewCommon = new PlanNewCommon(
+                                IdUtil.fastSimpleUUID(),
+                                f.name(),
+                                IdUtil.fastSimpleUUID(),
+                                f.type(),
+                                f.groupId(),
+                                f.posterTemplateId(),
+                                f.importDomain(),
+                                f.previewUrl(),
+                                f.configJson(),
+                                userName,
+                                userId,
+                                userName,
+                                userId,
+                                ZonedDateTime.now(),
+                                ZonedDateTime.now()
+                        );
+                        return template.insert(planNewCommon);
+                    });
+            Mono<List<PlanNewBackgroupPoster>> poster = template.select(Query.query(Criteria.where("plan_new_id")
+                            .is(planId)), PlanNewBackgroupPoster.class)
+                    .collectList();
+            Mono<String> stringMono = Mono.zip(planNewCommonMono, poster).flatMap(f -> {
+                PlanNewCommon 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.id(),
+                            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 -> {
+                        PlanNewCommon t11 = ff.getT1();
+                        return Mono.just(t11.id());
+                    });
+                } else {
+                    return Mono.just(t1.id());
+                }
+            });
+            return RStatus.success(stringMono);
+
+    }
+
+
+    /**
+     * 删除计划
+     * @param type
+     * @param planId
+     * @return {@link Mono}<{@link RStatus}<{@link Long}>>
+     */
+    @DeleteMapping("deleteById/{type}/{planId}")
+    public Mono<RStatus<Long>> deleteById(@PathVariable("type") @NotNull Integer type, @PathVariable("planId") @NotNull String planId) {
+       
+            // 交友计划
+            Query plan = Query.query(Criteria.where("id").is(planId));
+            Mono<Long> planNewCommon = template.delete(plan, PlanNewCommon.class)
+                    .switchIfEmpty(Mono.error(new BaseException("计划id异常")))
+                    .onErrorResume(throwable -> Mono.error(new Exception("删除计划 " + planId + "---" + type + "error:" + throwable.getMessage())));
+            Query planNewId = Query.query(Criteria.where("plan_new_id").is(planId));
+            Mono<Long> poster = template.count(planNewId, PlanNewBackgroupPoster.class).filter(f -> f > 0)
+                    .flatMap(f -> template.delete(planNewId, PlanNewBackgroupPoster.class))
+                    .switchIfEmpty(Mono.just(0L));
+            Mono<Long> longMono = Mono.zip(poster, planNewCommon).flatMap(f -> Mono.just(f.getT1()));
+            return RStatus.success(longMono);
+
+    }
+}

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

@@ -0,0 +1,913 @@
+package com.webflux.launchadmin.mysql.controller.planNew;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
+import com.webflux.launchadmin.global.BaseException;
+import com.webflux.launchadmin.mysql.controller.planNew.req.*;
+import com.webflux.launchadmin.mysql.controller.planNew.res.*;
+import com.webflux.launchadmin.mysql.controller.takeawayController.res.TakeawayH5Data;
+import com.webflux.launchadmin.mysql.entity.groupUsers.GroupUsers;
+import com.webflux.launchadmin.mysql.entity.listening.ListeningPlanNew;
+import com.webflux.launchadmin.mysql.entity.planNew.*;
+import com.webflux.launchadmin.mysql.entity.redis.RedisKey;
+import com.webflux.launchadmin.mysql.service.planNew.goGenerate.GoGenerateService;
+import com.webflux.launchadmin.mysql.service.planNew.ipAnalyze.IpAnalyzeServiceInterface;
+import com.webflux.launchadmin.mysql.service.planNew.structure.GoRequest;
+import com.webflux.launchadmin.mysql.service.planNew.structure.Item;
+import com.webflux.launchadmin.mysql.service.takeaway.TakeawayServicesInterface;
+import com.webflux.launchcommon.returnObj.RStatus;
+import com.webflux.launchcommon.utils.StringUtils;
+import jakarta.annotation.Resource;
+import jakarta.json.Json;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
+import org.springframework.data.redis.core.ReactiveRedisTemplate;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.data.relational.core.query.Criteria;
+import org.springframework.data.relational.core.query.Query;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.zip.GZIPOutputStream;
+
+/**
+ * 通用计划-H5
+ *
+ * @author: wangcheng
+ * @date: 2024/7/10 14:13
+ */
+@Slf4j
+@RestController
+@RequestMapping("out/planNewCommon")
+public class PlanNewCommonOutController {
+    @Resource
+    private R2dbcEntityTemplate template;
+    @Resource
+    private GoGenerateService goGenerateService;
+    @Resource
+    private ReactiveRedisTemplate<String, Object> reactiveRedisTemplate;
+    @Resource
+    private TakeawayServicesInterface takeawayServicesInterface;
+    @Resource
+    private IpAnalyzeServiceInterface ipAnalyzeServiceInterface;
+    private static final ConcurrentHashMap<String, Integer> MAP = new ConcurrentHashMap<>();
+
+    @Scheduled(cron = "1 1 4 * * ?")
+    public void clearUserContextHashMap() {
+        log.info("清空计划-H5用户Map数据》》》》》》》》》》》》》》》》》》》》》》开始");
+        MAP.clear();
+        log.info("清空计划-H5用户Map数据》》》》》》》》》》》》》》》》》》》》》》 结束");
+    }
+
+    /**
+     * 通过 code 获取计划配置H5信息
+     *
+     * @param code
+     * @return {@link Mono}<{@link RStatus}<{@link PlanNewCommon}>>
+     */
+    @GetMapping("getPlanNewCommonH5")
+    public Mono<RStatus<byte[]>> getPlanNewCommonH5(@RequestParam("code") String code, ServerWebExchange exchange) {
+
+
+        Mono<PlanNewCommon> planNewCommonMono = template.selectOne(Query.query(Criteria.where("code").is(code)), PlanNewCommon.class)
+                .switchIfEmpty(Mono.error(new BaseException("计划code异常")))
+                .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage() + "1")));
+        Mono<PlanNewCommonRes> resMono = planNewCommonMono.flatMap(f -> {
+            // 群成员
+            Mono<List<GroupUserRes>> groupUserResMono = Mono.just(new ArrayList<>());
+            // 群封面
+            Mono<List<Image>> imageMono = template.select(Query.query(Criteria.where("type").is(1)
+                            .and("group_type_id").is(f.groupId())
+                            .and("deleted_at").isNull()), Image.class)
+                    .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage() + "2"))).collectList();
+            // 群名称
+            Mono<List<Material>> textMono = template.select(Query.query(Criteria.where("type").is(4)
+                            .and("deleted_at").isNull()
+                            .and("group_type_id").is(f.groupId())), Material.class)
+                    .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage() + "3"))).collectList();
+            if (3 == f.type()) {
+                // 交友裂变, 需要群成员
+                Mono<List<GroupUsers>> groupUsersMono = template.select(Query.query(Criteria.where("group_users_type").is(f.groupId())).limit(14), GroupUsers.class)
+                        .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage() + "4"))).collectList();
+                groupUserResMono = groupUsersMono.flatMap(groupUsers -> {
+                    List<GroupUserRes> groupUserResList = groupUsers.stream().map(groupUsers1 -> {
+                        GroupUserRes groupUserRes = new GroupUserRes();
+                        groupUserRes.setUserHead(groupUsers1.groupUsersHead());
+                        groupUserRes.setUserNickname(groupUsers1.groupUsersNickname());
+                        return groupUserRes;
+                    }).collect(Collectors.toList());
+                    return Mono.just(groupUserResList);
+                });
+            }
+            return Mono.zip(Mono.just(f), groupUserResMono, imageMono, textMono).flatMap(tuple -> {
+                PlanNewCommon plan = tuple.getT1();
+                PlanNewCommonRes res = new PlanNewCommonRes();
+                res.setCode(plan.code());
+                res.setType(plan.type());
+                res.setName(plan.name());
+                res.setGroupId(plan.groupId());
+                res.setPosterTemplateId(plan.posterTemplateId());
+                res.setImportDomain(plan.importDomain());
+                res.setConfigJson(plan.configJson());
+                res.setGroupUserList(tuple.getT2());
+                List<H5ImageAndText> h5ImageAndTextList = new ArrayList<>();
+                H5ImageAndText h5ImageAndText = new H5ImageAndText();
+                List<Image> imageList = tuple.getT3();
+                if (!imageList.isEmpty()) {
+                    Image image = imageList.get(RandomUtil.randomInt(0, imageList.size()));
+                    h5ImageAndText.setImage(image.image());
+                }
+                List<Material> materialList = tuple.getT4();
+                if (!materialList.isEmpty()) {
+                    Material material = materialList.get(RandomUtil.randomInt(0, materialList.size()));
+                    String content = material.content();
+                    String clientIP=null ;//exchange.getRequest().getHeaders().getFirst("X-Forwarded-For");
+                    if ( Objects.nonNull(exchange.getRequest().getRemoteAddress())) {
+                        clientIP = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
+                    }
+                    if (StrUtil.isNotBlank(clientIP)) {
+                        JSONObject ipInfo = ipAnalyzeServiceInterface.getIpInfo(clientIP);
+                        if (null != ipInfo) {
+                            String city = ipInfo.getStr("city");
+                            if (StrUtil.isNotBlank(city)) {
+                                content = city + content;
+                            } else {
+                                String province = ipInfo.getStr("region");
+                                if (StrUtil.isNotBlank(province)) {
+                                    content = province + content;
+                                }
+                            }
+                        }
+                    }
+                    h5ImageAndText.setName(content);
+                    h5ImageAndText.setRemark(material.remark());
+                }
+                h5ImageAndTextList.add(h5ImageAndText);
+                res.setGroupImageAndTextList(h5ImageAndTextList);
+                return Mono.just(res);
+            });
+        });
+        // GZIP压缩
+        Mono<byte[]> res = resMono.flatMap(f -> Mono.just(Objects.requireNonNull(this.compressData(JSONUtil.toJsonStr(f)))));
+        return RStatus.success(res);
+    }
+
+    /**
+     * GZIP 压缩数据
+     */
+    private byte[] compressData(String data) {
+        try {
+            ByteArrayOutputStream stream = new ByteArrayOutputStream();
+            GZIPOutputStream gzipOS = new GZIPOutputStream(stream);
+            gzipOS.write(data.getBytes());
+            gzipOS.close();
+            return stream.toByteArray();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 客服列表
+     *
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link DataListsKefu}>>
+     */
+    @PostMapping("kefuList")
+    public Mono<RStatus<byte[]>> kefuList(@RequestBody KefuRequest request) {
+        Mono<PlanNewCommon> code = template.selectOne(Query.query(Criteria.where("code").is(request.getCode())), PlanNewCommon.class)
+                .switchIfEmpty(Mono.error(new BaseException("code查询返回结构为空")))
+                .onErrorResume(throwable -> Mono.error(new Exception("通过code查询计划异常::" + throwable.getMessage())));
+        Mono<DataListsKefu> dataListsKefuMono = code.flatMap(planNew -> {
+            Mono<List<Image>> image = template.select(Query.query(Criteria.where("type").is(5)
+                            .and("deleted_at").isNull()
+                            .and("group_type_id").is(planNew.groupId())), Image.class)
+                    .collectList()
+                    .switchIfEmpty(Mono.error(new BaseException(StrUtil.format("通过计划groupId:{}查询Image返回结构为空", planNew.groupId()))))
+                    .onErrorResume(throwable ->
+                            Mono.error(new Exception(StrUtil.format("通过计划groupId:{}查询Image返回结果error:{}", planNew.groupId(), throwable.getMessage()))));
+            Mono<List<Material>> text = template.select(Query.query(Criteria.where("type").is(11)
+                            .and("group_type_id").is(planNew.groupId())
+                            .and("deleted_at").isNull()), Material.class)
+                    .switchIfEmpty(Mono.error(new BaseException(StrUtil.format("通过计划groupId:{}查询Material返回结构为空", planNew.groupId()))))
+                    .onErrorResume(throwable ->
+                            Mono.error(new Exception(StrUtil.format("通过计划groupId:{}查询Material返回结果error:{}", planNew.groupId(), throwable.getMessage()))))
+                    .collectList();
+            Mono<List<H5ImageAndText>> arrayListMono = Mono.zip(Mono.just(planNew), image, text).flatMap(f -> {
+                // H5ImageAndText
+                // 群数量, 默认6
+                int integer = request.getPageShow() == null || request.getPageShow() <= 0 ? 6 : request.getPageShow();
+                List<Image> t3 = f.getT2();
+                List<Material> t4 = f.getT3();
+                if (t3.size() < integer || 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();
+                    List<Image> collect = t3.stream().filter(fff -> !listImg.contains(fff.id())).toList();
+                    if (!collect.isEmpty()) {
+                        Image image1 = collect.get(RandomUtil.randomInt(0, collect.size()));
+                        listImg.add(image1.id());
+                        h5ImageAndText.setImage(image1.image());
+                    }
+                    List<Material> collect1 = t4.stream().filter(fff -> !listTxt.contains(fff.id())).toList();
+                    if (!collect1.isEmpty()) {
+                        Material material = collect1.get(RandomUtil.randomInt(0, collect1.size()));
+                        listTxt.add(material.id());
+                        h5ImageAndText.setName(material.content());
+                        h5ImageAndText.setRemark(material.remark());
+                    }
+                    h5ImageAndTexts.add(h5ImageAndText);
+                });
+                return Mono.just(h5ImageAndTexts);
+            });
+            Mono<List<BackgroupImageItem>> backgroupImageItem = Mono.just(List.of());
+            if (Objects.nonNull(request.getBackgroundGroupId()) && request.getBackgroundGroupId() > 0) {
+                backgroupImageItem = Mono.just(planNew)
+                        .filter(ft -> Objects.nonNull(request.getBackgroundGroupId()))
+                        .flatMap(plan -> template.select(Query.query(Criteria.where("group_id")
+                                .is(request.getBackgroundGroupId())), BackgroupImageItem.class).collectList())
+                        .switchIfEmpty(Mono.just(List.of()));
+            }
+
+            Mono<Audio> retAudioId = this.getAudio(request.getRetAudioId());
+            Mono<DataListsKefu> dataListsMono = Mono.zip(Mono.just(planNew), backgroupImageItem, retAudioId, arrayListMono).flatMap(f -> {
+                DataListsKefu dataLists = new DataListsKefu();
+                dataLists.setPlanNewCommon(f.getT1());
+                dataLists.setBaiduDot(request.getBaiduDot());
+                List<BackgroupImageItem> t2 = f.getT2();
+                if (!t2.isEmpty()) {
+                    List<String> collect = t2.stream().map(BackgroupImageItem::image).collect(Collectors.toList());
+                    dataLists.setShareQrurl(collect);
+                }
+                if (Objects.nonNull(f.getT3().id())) {
+                    dataLists.setRetAudio(f.getT3());
+                }
+                dataLists.setImages(f.getT4());
+                return Mono.just(dataLists);
+            });
+            return dataListsMono;
+        });
+        // GZIP压缩
+        Mono<byte[]> res = dataListsKefuMono.flatMap(f -> Mono.just(Objects.requireNonNull(this.compressData(JSONUtil.toJsonStr(f)))));
+        return RStatus.successList(res);
+    }
+
+    /**
+     * 查询domain
+     *
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link DomainSelectRes}>>
+     */
+    @PostMapping("domainSelect")
+    public Mono<RStatus<DomainSelectRes>> domainSelect(@RequestBody OutDomainRequest request) {
+        if (1 == request.getTypePlan()) {
+            // 加群裂变
+            return this.getPlanNew(request);
+        } else if (2 == request.getTypePlan()) {
+            // 听书裂变
+            return this.getListeningPlan(request);
+        } else if(3==request.getTypePlan()){
+            // 交友裂变
+            return this.getFriendPlan(request);
+        }else if(4==request.getTypePlan()){
+            return this.getTakeaway(request);
+        }
+        throw new BaseException("typePlan 类型错误");
+    }
+
+    /**
+     * 加群裂变
+     */
+    private Mono<RStatus<DomainSelectRes>> getPlanNew(OutDomainRequest request) {
+        Mono<PlanNew> code1 = 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<DomainSelectRes> domainSelectResMono1 = code1.flatMap(f -> {
+            Mono<String> stringMono;
+            if (f.transferPageBl() == 1 && Objects.nonNull(f.transferPageDomain())) {
+                stringMono = template.select(Query.query(Criteria
+                                .where("group_type_id").is(f.transferPageDomain())
+                                .and("status").is(1)
+                                .and("type").is(5)
+                                .and("deleted_at").isNull()), DomainSelect.class)
+                        .switchIfEmpty(Mono.error(new BaseException("transferPageDomain 域名查詢為空 group_type_id:::" + f.transferPageDomain())))
+                        .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()))).collectList().flatMap(fff -> {
+                            if (!fff.isEmpty()) {
+                                DomainSelect domainSelect = fff.get(RandomUtil.randomInt(0, fff.size()));
+                                String string = RandomUtil.randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6);
+                                String domain1 = domainSelect.domain();
+                                return Mono.just(string + "." + domain1);
+
+                            } else {
+                                throw new BaseException("transferPageDomain 中轉域名查詢為空 group_type_id:::" + f.transferPageDomain());
+                            }
+                        });
+            } else {
+                stringMono = Mono.just(" ");
+            }
+            Mono<String> stringMono1;
+            if (Objects.nonNull(f.backgroupDomain()) && !f.backgroupDomain().trim().isEmpty()) {
+                stringMono1 = template.select(Query.query(Criteria
+                                .where("group_type_id").is(f.backgroupDomain())
+                                .and("status").is(1)
+                                .and("type").is(4)
+                                .and("deleted_at").isNull()), DomainSelect.class)
+                        .switchIfEmpty(Mono.error(new BaseException("backgroupDomain 域名查询为空 group_type_id" + f.backgroupDomain())))
+                        .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()))).collectList().flatMap(fff -> {
+                            if (!fff.isEmpty()) {
+                                DomainSelect domainSelect = fff.get(RandomUtil.randomInt(0, fff.size()));
+                                String string = RandomUtil.randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6);
+                                String domain1 = domainSelect.domain();
+                                return Mono.just(string + "." + domain1);
+                            } else {
+                                throw new BaseException("backgroupDomain 背景域名查詢為空 group_type_id" + f.backgroupDomain());
+                            }
+                        });
+            } else {
+                stringMono1 = Mono.just(" ");
+            }
+            Mono<String> stringMono2 = template.select(Query.query(Criteria
+                            .where("group_type_id").is(f.landingPageDomain())
+                            .and("status").is(1)
+                            .and("type").is(request.getType())
+                            .and("deleted_at").isNull()), DomainSelect.class)
+                    .switchIfEmpty(Mono.error(new BaseException("查询domain 返回结果为空")))
+                    .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()))).collectList().flatMap(fm -> {
+                        //  DomainSelectRes domainSelectRes = new DomainSelectRes();
+                        int i = RandomUtil.randomInt(0, fm.size());
+                        String domain = fm.get(i).domain();
+                        String string = RandomUtil.randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6);
+                        return Mono.just(string + "." + domain);
+                    });
+            return Mono.zip(stringMono2, stringMono1, stringMono).flatMap(fff -> {
+                DomainSelectRes domainSelectRes = new DomainSelectRes();
+                domainSelectRes.setDomain(fff.getT1());
+                domainSelectRes.setPath("");
+                domainSelectRes.setTransferPageBl(f.transferPageBl());
+                domainSelectRes.setBackgroupDomain(fff.getT2());
+                domainSelectRes.setTransferPageDomain(fff.getT3());
+                domainSelectRes.setUnique(IdUtil.fastSimpleUUID());
+                return Mono.just(domainSelectRes);
+            });
+        });
+        return RStatus.success(domainSelectResMono1);
+    }
+
+    /**
+     * 听书裂变
+     */
+    private Mono<RStatus<DomainSelectRes>> getListeningPlan(OutDomainRequest request) {
+        Mono<ListeningPlanNew> code1 = template.selectOne(Query.query(Criteria.where("code").is(request.getCode())), ListeningPlanNew.class)
+                .switchIfEmpty(Mono.error(new BaseException("计划code异常 返回结果为空")))
+                .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage())));
+        Mono<DomainSelectRes> domainSelectResMono1 = code1.flatMap(f -> template.select(Query.query(Criteria
+                        .where("group_type_id").is(f.groupId())
+                        .and("status").is(1)
+                        .and("type").is(request.getType())
+                        .and("deleted_at").isNull()), DomainSelect.class)
+                .switchIfEmpty(Mono.error(new BaseException("查询domain 返回结果为空")))
+                .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()))).collectList()
+                .flatMap(fm -> {
+                    DomainSelectRes domainSelectRes = new DomainSelectRes();
+                    int i = RandomUtil.randomInt(0, fm.size());
+                    String domain = fm.get(i).domain();
+                    String string = RandomUtil.randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6);
+                    domainSelectRes.setDomain(string + "." + domain);
+                    domainSelectRes.setPath("");
+                    domainSelectRes.setUnique(IdUtil.fastSimpleUUID());
+                    return Mono.just(domainSelectRes);
+                }));
+        return RStatus.success(domainSelectResMono1);
+    }
+
+    /**
+     * 交友裂变
+     */
+    private Mono<RStatus<DomainSelectRes>> getFriendPlan(OutDomainRequest request) {
+        Mono<String> stringMono;
+        if (StrUtil.isBlank(request.getLandingPageDomain()) || request.getLandingPageDomain().trim().isEmpty()) {
+            stringMono = Mono.just(" ");
+        } else {
+            stringMono = template.select(Query.query(Criteria
+                            .where("group_type_id").is(request.getLandingPageDomain())
+                            .and("status").is(1)
+                            .and("deleted_at").isNull()
+                            .and("type").is(request.getType())), DomainSelect.class)
+                    .switchIfEmpty(Mono.error(new BaseException("查询domain 返回结果为空")))
+                    .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage())))
+                    .collectList().flatMap(fm -> {
+                        int i = RandomUtil.randomInt(0, fm.size());
+                        String domain = fm.get(i).domain();
+                        String string = RandomUtil.randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6);
+                        return Mono.just(string + "." + domain);
+                    });
+        }
+        Mono<String> transferPageDomain;
+        if ( Objects.nonNull(request.getTransferPageDomain()) && StringUtils.isNotEmpty(request.getTransferPageDomain())) {
+            transferPageDomain = template.select(Query.query(Criteria
+                    .where("group_type_id").is(request.getTransferPageDomain())
+                    .and("status").is(1)
+                    .and("type").is(5)
+                    .and("deleted_at").isNull()), DomainSelect.class)
+                    .switchIfEmpty(Mono.error(new BaseException("transferPageDomain 域名查詢為空 group_type_id:::" + request.getTransferPageDomain())))
+                    .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()))).collectList().flatMap(fff -> {
+                        if (!fff.isEmpty()) {
+                            DomainSelect domainSelect = fff.get(RandomUtil.randomInt(0, fff.size()));
+                            String string = RandomUtil.randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6);
+                            String domain1 = domainSelect.domain();
+                            return Mono.just(string + "." + domain1);
+                        } else {
+                            throw new BaseException("transferPageDomain 中轉域名查詢為空 group_type_id:::" +  request.getTransferPageDomain());
+                        }
+                    });
+        } else {
+            transferPageDomain = Mono.just(" ");
+        }
+        Mono<String> backgroupDomain;
+        if (Objects.nonNull(request.getBackgroupDomain()) && StringUtils.isNotEmpty(request.getBackgroupDomain())) {
+            backgroupDomain = template.select(Query.query(Criteria
+                    .where("group_type_id").is(request.getBackgroupDomain())
+                    .and("status").is(1)
+                    .and("type").is(4)
+                    .and("deleted_at").isNull()), DomainSelect.class)
+                    .switchIfEmpty(Mono.error(new BaseException("backgroupDomain 域名查询为空 group_type_id" + request.getBackgroupDomain())))
+                    .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()))).collectList().flatMap(fff -> {
+                        if (!fff.isEmpty()) {
+                            DomainSelect domainSelect = fff.get(RandomUtil.randomInt(0, fff.size()));
+                            String string = RandomUtil.randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6);
+                            String domain1 = domainSelect.domain();
+                            return Mono.just(string + "." + domain1);
+                        } else {
+                            throw new BaseException("backgroupDomain 背景域名查詢為空 group_type_id" + request.getBackgroupDomain());
+                        }
+                    });
+        } else {
+            backgroupDomain = Mono.just(" ");
+        }
+        Mono<DomainSelectRes> res = Mono.zip(stringMono,transferPageDomain,backgroupDomain).flatMap(tuple3 -> {
+            DomainSelectRes domainSelectRes = new DomainSelectRes();
+            domainSelectRes.setDomain(tuple3.getT1());
+            domainSelectRes.setTransferPageDomain(tuple3.getT2());
+            domainSelectRes.setBackgroupDomain(tuple3.getT3());
+            domainSelectRes.setPath("");
+            domainSelectRes.setUnique(IdUtil.fastSimpleUUID());
+            return Mono.just(domainSelectRes);
+        });
+        return RStatus.success(res);
+    }
+    private Mono<RStatus<DomainSelectRes>> getTakeaway(OutDomainRequest request) {
+        Mono<String> stringMono;
+        if (StrUtil.isBlank(request.getLandingPageDomain()) || request.getLandingPageDomain().trim().isEmpty()) {
+            stringMono = Mono.just(" ");
+        } else {
+            stringMono = template.select(Query.query(Criteria
+                    .where("group_type_id").is(request.getLandingPageDomain())
+                    .and("status").is(1)
+                    .and("deleted_at").isNull()
+                    .and("type").is(request.getType())), DomainSelect.class)
+                    .switchIfEmpty(Mono.error(new BaseException("查询domain 返回结果为空")))
+                    .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage())))
+                    .collectList().flatMap(fm -> {
+                        int i = RandomUtil.randomInt(0, fm.size());
+                        String domain = fm.get(i).domain();
+                        String string = RandomUtil.randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6);
+                        return Mono.just(string + "." + domain);
+                    });
+        }
+        Mono<DomainSelectRes> res = stringMono.flatMap(fff -> {
+            DomainSelectRes domainSelectRes = new DomainSelectRes();
+            domainSelectRes.setDomain(fff);
+            domainSelectRes.setPath("");
+            domainSelectRes.setUnique(IdUtil.fastSimpleUUID());
+            return Mono.just(domainSelectRes);
+        });
+        return RStatus.success(res);
+    }
+
+    /**
+     * 查询落地页素材
+     *
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link PlanNewCommonMaterialRes}>>
+     */
+    @PostMapping("getCommonMaterial")
+    public Mono<RStatus<PlanNewCommonMaterialRes>> getCommonMaterial(@RequestBody PlanNewCommonMaterialReq request) {
+        Mono<PlanNewCommon> planNewCommonMono = template.selectOne(Query.query(Criteria.where("code").is(request.getCode())), PlanNewCommon.class)
+                .switchIfEmpty(Mono.error(new BaseException("计划code异常 返回结果为空")))
+                .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage())));
+        Mono<PlanNewCommonMaterialRes> materialResMono = planNewCommonMono.flatMap(plan -> {
+            // 群音频
+            Mono<Audio> groupAudio = this.getAudio(request.getAudioId());
+            // 返回音频
+            Mono<Audio> retAudio = this.getAudio(request.getRetAudioId());
+            // 返回广告
+            Mono<ReturnLoop> returnLoop;
+            if (Objects.isNull(request.getReturnLoopId()) || request.getReturnLoopId() <= 0) {
+                returnLoop = Mono.just(getReturnLoop());
+            } else {
+                returnLoop = template.selectOne(Query.query(Criteria.where("id").is(request.getReturnLoopId())
+                                .and("deleted_at").isNull()), ReturnLoop.class)
+                        .switchIfEmpty(Mono.just(getReturnLoop()))
+                        .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage() + "3")));
+            }
+            // 分享背景组
+            Mono<List<BackgroupImageItem>> backgroupImageItemMono;
+            if (Objects.isNull(request.getBackgroundGroupId()) || request.getBackgroundGroupId() <= 0) {
+                backgroupImageItemMono = Mono.just(List.of());
+            } else {
+                backgroupImageItemMono = template.select(Query.query(Criteria
+                                .where("group_id").is(request.getBackgroundGroupId())), BackgroupImageItem.class).collectList()
+                        .switchIfEmpty(Mono.just(List.of()))
+                        .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage() + "4")));
+            }
+            Mono<TakeawayH5Data> takeaway ;
+            if (Objects.nonNull(request.getTakeawayId()) && request.getTakeawayId() > 0) {
+                takeaway = takeawayServicesInterface.getTakeaway(request.getTakeawayId())
+                        .switchIfEmpty(Mono.error(new BaseException("查询外卖模版数据异常 查询结果为空")))
+                        .onErrorResume(e->Mono.error(new BaseException("查询外卖模版数据异常:::"+e.getMessage())));
+            }else {
+                takeaway=Mono.just(new TakeawayH5Data());
+            }
+            return Mono.zip(groupAudio, retAudio, returnLoop, backgroupImageItemMono,takeaway).flatMap(f -> {
+                PlanNewCommonMaterialRes materialRes = new PlanNewCommonMaterialRes();
+                materialRes.setGroupAudio(f.getT1());
+                materialRes.setRetAudio(f.getT2());
+                materialRes.setReturnLoop(f.getT3());
+                materialRes.setTakeawayH5Data(f.getT5());
+                if (!f.getT4().isEmpty()) {
+                    materialRes.setShareUrls(f.getT4().stream().map(BackgroupImageItem::image).collect(Collectors.toList()));
+                }
+                return Mono.just(materialRes);
+            });
+        });
+        // GZIP压缩
+        // Mono<byte[]> res = materialResMono.flatMap(f -> Mono.just(Objects.requireNonNull(this.compressData(JSONUtil.toJsonStr(f)))));
+        return RStatus.success(materialResMono);
+    }
+
+    /**
+     * 获取音频
+     */
+    private Mono<Audio> getAudio(Long id) {
+        if (Objects.isNull(id) || id <= 0) {
+            return Mono.just(getAudio());
+        }
+        // 优先读缓存
+        Mono<Object> obj = reactiveRedisTemplate.opsForValue().get(RedisKey.FISSION_AUDIO + id)
+                .switchIfEmpty(Mono.just(" "));
+        return obj.flatMap(val -> {
+            if (val != null && StrUtil.isNotBlank(val.toString())) {
+                Audio audio = JSON.parseObject(val.toString(), Audio.class);
+                return Mono.just(audio);
+            } else {
+                return template.selectOne(Query.query(Criteria.where("id").is(id)), Audio.class)
+                        .switchIfEmpty(Mono.error(new BaseException(StrUtil.format("通过计划retAudioId:{}查询音频为空", id))))
+                        .onErrorResume(throwable -> Mono.error(new BaseException(StrUtil.format("通过计划retAudioId:{}查询音频Error::", id, throwable.getMessage()))));
+            }
+        });
+    }
+
+    private Audio getAudio() {
+        return new Audio(null, null, null, null, null, null, null, null);
+    }
+
+    private ReturnLoop getReturnLoop() {
+        return new ReturnLoop(-1L, null, null, null, null, null, null, null, null, null, null, null, null, null);
+    }
+
+    /**
+     * H5分享
+     *
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link PlanNewCommonShareRes}>>
+     */
+    @PostMapping("planCommonShare")
+    public Mono<RStatus<PlanNewCommonShareRes>> planCommonShare(@RequestBody PlanNewCommonShareReq 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<PlanNewCommon> planNewCommonMono = template.selectOne(Query.query(Criteria.where("code").is(request.getCode())), PlanNewCommon.class)
+                .switchIfEmpty(Mono.error(new BaseException(" code错误")))
+                .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage())));
+        Mono<PlanNewCommonShareRes> resMono = planNewCommonMono.flatMap(plan -> {
+            Mono<StringBuilder> stringBuilderMono;
+            boolean isQs = Objects.nonNull(request.getWx_user_id()) && !request.getWx_user_id().isEmpty();
+            if (3 == plan.type()) {
+                // 交友裂变无清水分类
+                isQs = false;
+            }
+            if (Objects.nonNull(request.getRedirectType()) && request.getRedirectType() == 2) {
+                stringBuilderMono = goGenerateService.byPlanNewIdGetUrlCommon(request.getRedirectPlanId(), isQs, request.getGroupIdQs());
+            } else {
+                stringBuilderMono = Mono.just(new StringBuilder(request.getLink()));
+            }
+            Mono<PlanNewCommon> code = Mono.just(plan);
+            return Mono.zip(code, getPosterTemplate(code), getPoster(code), getPlanNewBackgroupPoster(code), getEwm(code), stringBuilderMono).flatMap(f -> {
+                PlanNewCommonShareRes res = new PlanNewCommonShareRes();
+                res.setPlanNew(f.getT1());
+                res.setPosterTemplate(f.getT2());
+                res.setSpare(f.getT5().toString());
+                res.setRedirectType(request.getRedirectType());
+                List<Poster> t3 = f.getT3();
+                if (!t3.isEmpty()) {
+                    if (t3.size() <= request.getUserVisits()) {
+                        res.setPoster(t3.getLast());
+                    } else {
+                        res.setPoster(t3.get(request.getUserVisits()));
+                    }
+                }
+                Map<Integer, List<PlanNewBackgroupPoster>> backgroupPoster = f.getT4().stream().collect(Collectors.groupingBy(PlanNewBackgroupPoster::qsOrFx));
+                // 营销-清水, 交友裂变无清水背景
+                if (Objects.nonNull(request.getWx_user_id()) && !request.getWx_user_id().isEmpty() && 3 != plan.type()) {
+                    List<PlanNewBackgroupPoster> qs = backgroupPoster.get(2).stream()
+                            .sorted(Comparator.comparing(PlanNewBackgroupPoster::index))
+                            .toList();
+                    if (!qs.isEmpty()) {
+                        if (qs.size() <= request.getUserVisits()) {
+                            Integer userVisits = request.getUserVisits();
+                            int v = userVisits % qs.size();
+                            res.setQsSetting(qs.get(v));
+                            if (f.getT6().toString().isEmpty()) {
+                                throw new BaseException("计划链接 查询匹配域名为空");
+                            }
+                            res.setLink(f.getT6().toString());
+                        } else {
+                            res.setQsSetting(qs.get(request.getUserVisits()));
+                            res.setLink(null);
+                        }
+                    }
+                    PlanNewBackgroupPoster qsSetting = res.getQsSetting();
+                    if (Objects.nonNull(qsSetting)) {
+                        res.setLimitTime(qsSetting.limitTime());
+                        res.setLimitTimeRemark(qsSetting.limitTimeRemark());
+                    }
+                } else {
+                    List<PlanNewBackgroupPoster> fx = backgroupPoster.get(1).stream()
+                            .sorted(Comparator.comparing(PlanNewBackgroupPoster::index)).toList();
+                    if (!fx.isEmpty()) {
+                        if (fx.size() <= request.getUserVisits()) {
+                            Integer userVisits = request.getUserVisits();
+                            int v = userVisits % fx.size();
+                            res.setFxSetting(fx.get(v));
+                            if (f.getT6().toString().isEmpty()) {
+                                throw new BaseException("计划链接 查询匹配域名为空");
+                            }
+                            res.setLink(f.getT6().toString());
+                        } else {
+                            res.setLink(null);
+                            res.setFxSetting(fx.get(request.getUserVisits()));
+                        }
+                    }
+                    PlanNewBackgroupPoster fxSetting = res.getFxSetting();
+                    if (Objects.nonNull(fxSetting)) {
+                        res.setLimitTime(fxSetting.limitTime());
+                        res.setLimitTimeRemark(fxSetting.limitTimeRemark());
+                    }
+                }
+                return Mono.just(res);
+            });
+        });
+        Mono<PlanNewCommonShareRes> resMono1 = this.setEndData(request, setFmV(setAudioV(request, resMono)));
+        // GZIP压缩
+        // Mono<byte[]> res = resMono1.flatMap(f -> Mono.just(Objects.requireNonNull(this.compressData(JSONUtil.toJsonStr(f)))));
+        return RStatus.successList(resMono1);
+    }
+    private QrcodeInfo getQrcodeInfo(GoRequest goRequest)  {
+        Optional<Item> first = goRequest.getItem().stream().filter(ff -> "cover".equals(ff.getT()) ).findFirst();
+        Optional<Item> first3 = goRequest.getItem().stream().filter(ff -> "title".equals(ff.getT())).findFirst();
+        QrcodeInfo qrcodeInfo = new QrcodeInfo(null,first.isPresent()?first.get().getV():"",first3.isPresent()?first3.get().getV():"");
+        return qrcodeInfo;
+    }
+    /**
+     * 设置二维码 生成图片
+     */
+    private Mono<PlanNewCommonShareRes> setEndData(PlanNewCommonShareReq request, Mono<PlanNewCommonShareRes> resMono) {
+        Mono<PlanNewCommonShareRes> resMono1 = resMono.flatMap(fm -> {
+            Poster poster = fm.getPoster();
+            if (Objects.isNull(poster)) {
+                return Mono.just(fm);
+            }
+            String posterTemplate = poster.posterTemplate();
+            GoRequest goRequest;
+            // 交友裂变无清水分类
+            if (Objects.nonNull(request.getWx_user_id()) && !request.getWx_user_id().isEmpty() && 3 != fm.getPlanNew().type()) {
+                PlanNewBackgroupPoster qsSetting = fm.getQsSetting();
+                goRequest = setNameVal(posterTemplate, qsSetting, fm.getSpare());
+            } else {
+                PlanNewBackgroupPoster fxSetting = fm.getFxSetting();
+                goRequest = setNameVal(posterTemplate, fxSetting, fm.getSpare());
+            }
+            QrcodeInfo stringBuilder = getQrcodeInfo(goRequest);
+            Mono<QrcodeInfo> qrcodeInfoMono=Mono.just(new QrcodeInfo(null,null,null));
+            List<Item> collect = goRequest.getItem()
+                    .stream()
+                    .filter(filter -> "cusqrcode".equals(filter.getT())
+                            && filter.getIsRandom()
+                            && 1 == filter.getType()).collect(Collectors.toList());
+            if (!collect.isEmpty()) {
+                 qrcodeInfoMono = template.insert(stringBuilder)
+                        .onErrorResume(throwable -> Mono.error(new BaseException("插入QrcodeInfo异常::::" + throwable.getMessage())));
+            }
+          return   Mono.zip(Mono.just(fm),qrcodeInfoMono).flatMap(fm1->{
+                if (Objects.nonNull(fm1.getT2().id())) {
+                    goRequest.getItem()
+                            .stream()
+                            .filter(filter -> "cusqrcode".equals(filter.getT())
+                                    && filter.getIsRandom()
+                                    && 1 == filter.getType()).collect(Collectors.toList()).forEach(fe -> {
+                        if (Objects.nonNull(fe.getV())) {
+                            if (fe.getV().contains("?")){
+                                String cusqrcode = fe.getV() + "&id=" + fm1.getT2().id();
+                                fe.setV(cusqrcode);
+                            }else{
+                                String cusqrcode = fe.getV() + "?id=" + fm1.getT2().id();
+                                fe.setV(cusqrcode);
+                            }
+                        }
+                    });
+                }
+                String  ret = goGenerateService.goGenerate(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")) {
+                            String url = data.get("Url", String.class);
+                            if (Objects.nonNull(request.getWx_user_id()) && !request.getWx_user_id().isEmpty() && 3 != fm.getPlanNew().type()) {
+                                fm1.getT1().setQsGenerateImagesUrl(url);
+                            } else {
+                                fm1.getT1().setFxGenerateImagesUrl(url);
+                            }
+
+                        }
+                    }
+                }
+                return Mono.just(fm);
+            });
+        });
+        return resMono1;
+    }
+
+    /**
+     * qrcode 二维码设置
+     */
+    private GoRequest setNameVal(String posterTemplate, PlanNewBackgroupPoster qsSetting, String spare) {
+        JSONObject jsonObject;
+        try {
+            jsonObject = JSONUtil.parseObj(posterTemplate);
+        } catch (Exception e) {
+            throw new BaseException(e.getMessage() + "---" + posterTemplate);
+        }
+        // JSONObject jsonObject = JSONUtil.parseObj(posterTemplate);
+        GoRequest goRequest = new GoRequest();
+        BeanUtil.copyProperties(jsonObject, goRequest);
+        if (Objects.nonNull(qsSetting)) {
+            Optional<Item> first = goRequest.getItem().stream().filter(f -> "qrcode".equals(f.getT())).findFirst();
+            if (first.isPresent()) {
+                Item item = first.get();
+                Boolean isRandom = item.getIsRandom();
+                if (isRandom && Objects.nonNull(qsSetting.status()) && qsSetting.status() == 1
+                        && Objects.nonNull(qsSetting.serviceGroupType()) && qsSetting.serviceGroupType() == 2) {
+                    String kefu = qsSetting.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("客服二维码");
+                            return goRequest;
+                        }
+                    }
+                } else if (Objects.nonNull(qsSetting.status()) && qsSetting.status() == 0) {
+                    item.setV(spare);
+                    item.setName("H5二维码");
+                    return goRequest;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 设置封面等
+     */
+    private Mono<PlanNewCommonShareRes> setFmV(Mono<PlanNewCommonShareRes> zip) {
+        Mono<PlanNewCommonShareRes> resMono = zip.flatMap(fm -> {
+            Poster poster = fm.getPoster();
+            if (Objects.isNull(poster)) {
+                return Mono.just(fm);
+            }
+            String posterTemplate = poster.posterTemplate();
+            JSONObject jsonObject;
+            try {
+                jsonObject = JSONUtil.parseObj(posterTemplate);
+            } catch (Exception e) {
+                throw new BaseException(e.getMessage() + "---" + posterTemplate);
+            }
+            GoRequest goRequest = new GoRequest();
+            BeanUtil.copyProperties(jsonObject, goRequest);
+            Mono<String> outTemPoster;
+
+            Long aLong = fm.getPlanNew().groupId();
+            outTemPoster = goGenerateService.getOutTemPosterYx(goRequest,
+                    goGenerateService.setCusqrcodeSetV(goRequest),
+                    aLong);
+
+            return Mono.zip(Mono.just(fm), outTemPoster, (a, b) -> {
+                Poster poster1 = new Poster(poster.posterId(),
+                        poster.posterTemplateId(),
+                        b,
+                        poster.createUser(),
+                        poster.createId(),
+                        poster.createdAt(),
+                        poster.updatedAt(),
+                        poster.generateImagesJson(),
+                        poster.generateImagesUrl());
+                a.setPoster(poster1);
+                return a;
+            });
+        });
+        return resMono;
+    }
+
+    /**
+     * 音频
+     */
+    private Mono<PlanNewCommonShareRes> setAudioV(PlanNewCommonShareReq request, Mono<PlanNewCommonShareRes> resMono) {
+        Mono<PlanNewCommonShareRes> zip = resMono.flatMap(f -> {
+            Mono<Audio> id = null;
+            if (Objects.nonNull(request.getWx_user_id()) && !request.getWx_user_id().isEmpty() && 3 != f.getPlanNew().type()) {
+                PlanNewBackgroupPoster qsSetting = f.getQsSetting();
+                if (Objects.nonNull(qsSetting) && Objects.nonNull(qsSetting.audioId()) && 0 != qsSetting.audioId()) {
+                    id = template.selectOne(Query.query(Criteria.where("id").is(qsSetting.audioId()).and("deleted_at").isNull()), Audio.class);
+                }
+            } else {
+                PlanNewBackgroupPoster fxSetting = f.getFxSetting();
+                if (Objects.nonNull(fxSetting) && Objects.nonNull(fxSetting.audioId()) && 0 != fxSetting.audioId()) {
+                    id = template.selectOne(Query.query(Criteria.where("id").is(fxSetting.audioId()).and("deleted_at").isNull()), Audio.class);
+                }
+            }
+            if (Objects.isNull(id)) {
+                return Mono.just(f);
+            }
+            return Mono.zip(Mono.just(f), id, (a, b) -> {
+                a.setAudio(b);
+                return a;
+            });
+        });
+        return zip;
+    }
+
+    private Mono<List<PlanNewBackgroupPoster>> getPlanNewBackgroupPoster(Mono<PlanNewCommon> code) {
+        return code.flatMap(plan -> template.select(Query.query(Criteria.where("plan_new_id")
+                        .is(plan.id())).sort(Sort.by(Sort.Order.asc("idx"))), PlanNewBackgroupPoster.class)
+                .collectList());
+    }
+
+    private Mono<List<Poster>> getPoster(Mono<PlanNewCommon> 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());
+    }
+
+    private Mono<PosterTemplate> getPosterTemplate(Mono<PlanNewCommon> code) {
+        return code.flatMap(plan -> template.selectOne(Query.query(Criteria.where("poster_template_id")
+                .is(plan.posterTemplateId())), PosterTemplate.class));
+    }
+
+    private Mono<StringBuilder> getEwm(Mono<PlanNewCommon> code) {
+        return goGenerateService.getOutImportDomainCommon(code);
+    }
+}

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

@@ -0,0 +1,1084 @@
+package com.webflux.launchadmin.mysql.controller.planNew;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.RandomUtil;
+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.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;
+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.relational.core.query.Criteria;
+import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
+import org.springframework.data.relational.core.query.Query;
+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.Comparator;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+
+/**
+ * 计划
+ *
+ * @author lw12420
+ * @date 2024/05/21
+ */
+@RestController
+@RequestMapping("in/planNew")
+public class PlanNewController {
+    // 一天时间
+    @Resource
+    private R2dbcEntityTemplate template;
+
+    @Resource
+    private GoGenerateService goGenerateService;
+    @Resource
+    private ListeningPlanServiceInterface listeningPlanService;
+    @Resource
+    private PlanServiceInterface planServiceInterface;
+
+    @GetMapping("tt")
+    public String tt() {
+        String str = "{\"item\": [{\"a\": \"left\", \"c\": \"rgba(0, 0, 0, 1)\", \"h\": 20, \"s\": 14, \"t\": \"title\", \"v\": \"群聊,本地视频推荐\", \"w\": 140, \"x\": 100, \"y\": 100, \"fn\": \"ali-Regular\", \"rm\": \"备注\", \"bgc\": \"\", \"name\": \"海报标题\", \"uuid\": \"b3a10a5e-8c17-4a37-9a99-13600328868c\", \"warp\": false, \"weight\": 500}, {\"c\": \"rgba(0, 0, 0, 1)\", \"h\": 300, \"t\": \"qrcode\", \"v\": \"\", \"w\": 300, \"x\": 87, \"y\": 172, \"fn\": \"\", \"rm\": \"备注\", \"bgc\": \"#ffffff\", \"name\": \"二维码\", \"uuid\": \"2862c036-ad07-48d4-ab34-94fbb2c46c30\"}], \"width\": 458, \"height\": 709, \"bg_img_src\": \"\"}";
+
+        return goGenerateService.goGenerate(str);
+    }
+
+
+    /**
+     * 分享、清水背景组-回显
+     *
+     * @param planNewId 计划id
+     * @param qsOrFx    1:营销 2:清水
+     * @return {@link Mono}<{@link RStatus}<{@link BackgroupImageRes}>>
+     */
+    @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异常");
+    }
+
+    /**
+     * 背景组详情接口
+     *
+     * @param id 背景组id
+     * @return {@link Mono}<{@link RStatus}<{@link DataLists}>>
+     */
+    @GetMapping("backgroupImageRes/{id}")
+    public Mono<RStatus<BackgroupImageRes>> backgroupImageRes(@PathVariable("id") Long id) {
+        Mono<BackgroupImage> id1 = template.selectOne(Query.query(Criteria.where("id")
+                        .is(id)), BackgroupImage.class).switchIfEmpty(Mono.error(new BaseException(" 通过code查询结果为空")))
+                .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage())));
+        Mono<List<BackgroupImageItem>> group_id = template.select(Query.query(Criteria.where("group_id")
+                .is(id)).sort(Sort.by(Sort.Order.asc("index"))), BackgroupImageItem.class).collectList();
+        Mono<BackgroupImageRes> zip = Mono.zip(id1, group_id, (lambdaA, lambdaB) -> {
+            BackgroupImageRes backgroupImageRes = new BackgroupImageRes();
+            backgroupImageRes.setBackgroupImage(lambdaA);
+            backgroupImageRes.setBackgroupImageItemList(lambdaB);
+            return backgroupImageRes;
+        });
+        return RStatus.successList(zip);
+    }
+
+
+    /**
+     * 客服组-下拉 ( By status)
+     *
+     * @param status
+     * @return {@link Mono}<{@link RStatus}<{@link List}<{@link ReturnLoop}>>>
+     */
+    @GetMapping("serviceGroupSlt")
+    public Mono<RStatus<List<ServiceGroup>>> serviceGroupSlt(@RequestParam("status") Integer status) {
+        Mono<List<ServiceGroup>> status1 = template.select(Query.query(Criteria.where("status")
+                .is(2)), ServiceGroup.class).collectList();
+        return RStatus.successList(status1);
+
+    }
+
+    /**
+     * 素材、清水--分类下拉(groupType)名称模糊查询
+     *
+     * @param name
+     * @return {@link Mono}<{@link RStatus}<{@link Long}>>
+     */
+    @GetMapping("groupTypeSlt")
+    public Mono<RStatus<List<GroupType>>> groupTypeSlt(@RequestParam("name") String name, @RequestParam("groupType") String groupType) {
+        Criteria criteria = Criteria.where("group_type").is(groupType);
+        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);
+    }
+
+    /**
+     * 返回广告下拉名称模糊查询
+     *
+     * @param name
+     * @return {@link Mono}<{@link RStatus}<{@link Long}>>
+     */
+    @GetMapping("retrunloopSlt")
+    public Mono<RStatus<List<ReturnLoop>>> retrunloopSlt(@RequestParam("name") String name) {
+        Criteria criteria = Criteria.empty(); // poster_template_id
+        if (Objects.nonNull(name) && "" != name) {
+            criteria = criteria.and("name").like("%" + name + "%");
+        }
+        Mono<List<ReturnLoop>> listMono = template.select(Query.query(criteria), ReturnLoop.class).collectList();
+        return RStatus.success(listMono);
+    }
+
+    /**
+     * (分享/清水)背景组设置下拉名称模糊查询
+     *
+     * @param name groupType
+     * @return {@link Mono}<{@link RStatus}<{@link Long}>>
+     */
+    @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 + "%");
+        }
+        Mono<List<BackgroupImage>> listMono = template.select(Query.query(criteria), BackgroupImage.class).collectList();
+        return RStatus.success(listMono);
+    }
+
+    /**
+     * 音频下拉名称模糊查询
+     *
+     * @param name
+     * @return {@link Mono}<{@link RStatus}<{@link Long}>>
+     */
+    @GetMapping("audioSlt")
+    public Mono<RStatus<List<Audio>>> audio(@RequestParam("name") String name) {
+        Criteria criteria = Criteria.empty(); // poster_template_id
+        if (Objects.nonNull(name) && "" != name) {
+            criteria = criteria.and("name").like("%" + name + "%");
+        }
+        Mono<List<Audio>> listMono = template.select(Query.query(criteria), Audio.class).collectList();
+        return RStatus.success(listMono);
+    }
+
+    /**
+     * 海报保存
+     *
+     * @param posterRequset
+     * @return {@link Mono}<{@link RStatus}<{@link PlanNew}>>
+     */
+    @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();
+    }
+
+    /**
+     * 海报修改
+     *
+     * @param posterRequset
+     * @return {@link Mono}<{@link RStatus}<{@link PlanNew}>>
+     */
+    @PostMapping("updatePoster")
+    public Mono<RStatus<Poster>> updatePoster(@RequestBody PosterRequest posterRequset) {
+        return goGenerateService.updatePoster(posterRequset);
+    }
+
+    /**
+     * 海报删除
+     *
+     * @param posterId
+     * @return {@link Mono}<{@link RStatus}<{@link Long}>>
+     */
+    @DeleteMapping("deletePosterById/{posterId}")
+    public Mono<RStatus<Long>> deletePosterById(@PathVariable("posterId") @NotNull Long posterId) {
+        Mono<Long> plan_new_id = template.delete(Query.query(Criteria.where("poster_id").is(posterId)), Poster.class);
+        return RStatus.success(plan_new_id);
+    }
+
+    /**
+     * 海报列表
+     *
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link Paged}<{@link PosterTemplate}>>>
+     */
+    @PostMapping("posterList")
+    public Mono<RStatus<Paged<Poster>>> posterList(@RequestBody PosterPage request) {
+        Criteria criteria = Criteria.empty(); // poster_template_id
+        criteria = criteria.and("poster_template_id").is(request.getPosterTemplateId());
+        Query query = Query.query(criteria);
+        Criteria finalCriteria = criteria;
+        int skip = (request.getPage() - 1) * request.getSize();
+        int limit = request.getSize();
+        Mono<Paged<Poster>> pagedMono = template.count(query, Poster.class).flatMap(fm ->
+                template.select(Query.query(finalCriteria)
+                                .offset(skip)
+                                .limit(limit)
+                                .sort(Sort.by(Sort.Order.asc("created_at"))), Poster.class)
+                        .collectList()
+                        .map(list -> new Paged<>(fm, list, request.getPage(), request.getSize()))
+        );
+        return RStatus.successList(pagedMono);
+    }
+
+    /**
+     * 海报模版保存
+     *
+     * @param posterTemplateRequset
+     * @return {@link Mono}<{@link RStatus}<{@link PlanNew}>>
+     */
+    @PostMapping("savePosterTem")
+    public Mono<RStatus<PosterTemplate>> savePosterTem(@RequestBody PosterTemplateRequset posterTemplateRequset) {
+        PosterTemplate posterTemplate = new PosterTemplate(null, posterTemplateRequset.getPosterTemplateName(), BaseContextHandler.getUserName(),
+                BaseContextHandler.getUserId(), ZonedDateTime.now(),
+                ZonedDateTime.now());
+        Mono<PosterTemplate> insert = template.insert(posterTemplate);
+        return RStatus.success(insert);
+    }
+
+    /**
+     * 海报模版修改
+     *
+     * @param posterTemplateRequset
+     * @return {@link Mono}<{@link RStatus}<{@link PlanNew}>>
+     */
+    @PostMapping("updatePosterTem")
+    public Mono<RStatus<Long>> updatePosterTem(@RequestBody PosterTemplateRequset posterTemplateRequset) {
+
+        Criteria empty = Criteria.where("poster_template_id").is(posterTemplateRequset.getPosterTemplateId());
+        Update update = Update.update("updated_at", ZonedDateTime.now());
+        if (Objects.nonNull(posterTemplateRequset.getPosterTemplateName()) && !"".equals(posterTemplateRequset.getPosterTemplateName())) {
+            update = update.set("poster_template_name", posterTemplateRequset.getPosterTemplateName());
+        }
+        Mono<Long> update1 = template.update(Query.query(empty), update, PosterTemplate.class);
+        return RStatus.success(update1);
+    }
+
+    /**
+     * 海报模版删除
+     *
+     * @param posterTemplateId
+     * @return {@link Mono}<{@link RStatus}<{@link Long}>>
+     */
+    @DeleteMapping("deletePosterTemById/{posterTemplateId}")
+    public Mono<RStatus<Long>> deletePosterTemById(@PathVariable("posterTemplateId") @NotNull Long posterTemplateId) {
+        Mono<Long> plan_new_id = template.delete(Query.query(Criteria.where("poster_template_id").is(posterTemplateId)), PosterTemplate.class);
+        return RStatus.success(plan_new_id);
+    }
+
+    /**
+     * 海报模版-编辑回显详情
+     *
+     * @param posterTemplateId
+     * @return
+     */
+    @GetMapping("posterTem/{planNewId}")
+    public Mono<RStatus<PosterTemplate>> posterTem(@PathVariable("posterTemplateId") @NotNull Long posterTemplateId) {
+        Mono<PosterTemplate> planNewMono = template
+                .selectOne(Query.query(Criteria.where("poster_template_id")
+                        .is(posterTemplateId)), PosterTemplate.class);
+        return RStatus.success(planNewMono);
+    }
+
+    /**
+     * 海报模版下拉
+     *
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link Paged}<{@link PosterTemplate}>>>
+     */
+    @PostMapping("posterTemSelect")
+    public Mono<RStatus<List<PosterTemplate>>> posterTemSelect(@RequestBody PosterTemSelect request) {
+        Criteria criteria = Criteria.empty(); // poster_template_id
+        if (Objects.nonNull(request.getName()) && "" != request.getName()) {
+            criteria = criteria.and("name").like(request.getName());
+        }
+        Mono<List<PosterTemplate>> listMono = template.select(Query.query(criteria).sort(Sort.by(Sort.Order.desc("created_at"))), PosterTemplate.class).collectList();
+        return RStatus.successList(listMono);
+    }
+
+    /**
+     * 海报模版-列表
+     *
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link Paged}<{@link PosterTemplate}>>>
+     */
+    @PostMapping("posterTemList")
+    public Mono<RStatus<Paged<PosterTemplateRes>>> posterTemList(@RequestBody PosterTemPage request) {
+        Criteria criteria = Criteria.empty(); // poster_template_id
+        if (Objects.nonNull(request.getName()) && "" != request.getName()) {
+            criteria = criteria.and("name").is(request.getName());
+        }
+        Query query = Query.query(criteria);
+        Criteria finalCriteria = criteria;
+        int skip = (request.getPage() - 1) * request.getSize();
+        int limit = request.getSize();
+        Mono<Long> count = template.count(query, PosterTemplate.class);
+        Flux<PosterTemplateRes> created_at = template.select(Query.query(finalCriteria)
+                .offset(skip)
+                .limit(limit)
+                .sort(Sort.by(Sort.Order.desc("created_at"))), PosterTemplate.class).flatMap(f ->
+                template.count(Query.query(Criteria.where("poster_template_id").is(f.posterTemplateId())), Poster.class).map(n -> {
+                    PosterTemplateRes posterTemplateRes1 = new PosterTemplateRes();
+                    posterTemplateRes1.setPosterTemplateId(f.posterTemplateId());
+                    posterTemplateRes1.setPosterTemplateName(f.posterTemplateName());
+                    posterTemplateRes1.setCreatedAt(f.createdAt());
+                    posterTemplateRes1.setNum(n);
+                    posterTemplateRes1.setCreateId(f.createId());
+                    posterTemplateRes1.setCreateUser(f.createUser());
+                    posterTemplateRes1.setUpdatedAt(f.updatedAt());
+                    return posterTemplateRes1;
+                })
+        );
+        Mono<List<PosterTemplateRes>> listMono = created_at.collectList();
+        Mono<Paged<PosterTemplateRes>> zip = Mono.zip(count, listMono, (fm, list) -> new Paged<PosterTemplateRes>(fm, list, request.getPage(), request.getSize())
+        );
+        return RStatus.successList(zip);
+    }
+
+
+    /**
+     * 计划保存
+     *
+     * @param saveRequest
+     * @return {@link Mono}<{@link RStatus}<{@link PlanNew}>>
+     */
+    @PostMapping("savePlan")
+    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.setCusqrcodeSetV(goRequest),// 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->{
+                String listButton="立即入群";
+                if(Objects.nonNull(saveRequest.getListButton()) && !"".equals(saveRequest.getListButton().trim())){
+                    listButton=saveRequest.getListButton();
+                }
+                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(),
+                        saveRequest.getImportDomain(),
+                        saveRequest.getLandingPageDomain(),
+                        saveRequest.getTransferPageDomain(),
+                        saveRequest.getTransferPageBl(),
+                        saveRequest.getBackgroupDomain(),
+                        listButton,
+                        saveRequest.getGroupListDisplay()
+                );
+                return template.insert(plan);
+            });
+            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 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);
+        });
+        Flux<PlanNewBackgroupPoster> just = Flux.fromIterable(listeningPlanNewBackgroupPosters);
+        return just;
+    }
+
+    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(),
+                request.getKefu(),
+                request.getLimitTime(),
+                request.getLimitTimeRemark(),
+                request.getStatus(),
+                request.getIndex(),
+                request.getServiceGroupId(),
+                request.getServiceGroupType(),
+                qsOrFx,
+                ZonedDateTime.now(),
+                null,
+                null,
+                planNewId, null, null);
+//         template.insert(planNewBackgroupPoster).subscribe(f->{
+//             JSONObject jsonObject = JSONUtil.parseObj(f);
+//             System.out.println(jsonObject);
+//         });
+
+    }
+
+
+    /**
+     * 修改计划
+     *
+     * @param saveRequest
+     * @return {@link Mono}<{@link RStatus}<{@link PlanNew}>>
+     */
+    @PostMapping("updatePlan")
+    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),
+                                goGenerateService.setCusqrcodeSetV(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();
+                String listButton="立即入群";
+                if(Objects.nonNull(saveRequest.getListButton()) && !"".equals(saveRequest.getListButton().trim())){
+                    listButton=saveRequest.getListButton();
+                }
+                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(),
+                        saveRequest.getImportDomain(),
+                        saveRequest.getLandingPageDomain(),
+                        saveRequest.getTransferPageDomain(),
+                        saveRequest.getTransferPageBl(),
+                        saveRequest.getBackgroupDomain(),
+                        listButton,
+                        saveRequest.getGroupListDisplay()
+                );
+                return Mono.just(planNew);
+            }).flatMap(template::update);
+            Mono<String> map = planNewMono.flatMap(f1 -> {
+                Mono<Long> ml = template.delete(Query.query(Criteria.where("plan_new_id").is(f1.planNewId())), PlanNewBackgroupPoster.class);
+                return Mono.zip(Mono.just(f1), ml).flatMap(ff -> Mono.just(f1));
+            }).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 RStatus.success(map);
+        }
+
+        throw new BaseException("type类型错误");
+    }
+    public void fxBackgroupSettingsUpdate( ServiceGroupSettingItemRequest request,String planNewId,Integer qsOrFx){
+        PlanNewBackgroupPoster planNewBackgroupPoster = new PlanNewBackgroupPoster(request.getId(),
+                request.getAudioId(),
+                request.getGroupId(),
+                request.getImage(),
+                request.getKefu(),
+                request.getLimitTime(),
+                request.getLimitTimeRemark(),
+                request.getStatus(),
+                request.getIndex(),
+                request.getServiceGroupId(),
+                request.getServiceGroupType(),
+                qsOrFx,
+                ZonedDateTime.now(),
+                ZonedDateTime.now(),
+                null,
+                planNewId,null,null);
+       // template.insert(planNewBackgroupPoster).subscribe();
+      //  return planNewBackgroupPoster;
+    }
+
+    /**
+     * 复制计划
+     *
+     * @param planNewId
+     * @return {@link Mono}<{@link RStatus}<{@link PlanNew}>>
+     */
+    @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(),
+                            saveRequest.importDomain(),
+                            saveRequest.landingPageDomain(),
+                            saveRequest.transferPageDomain(),
+                            saveRequest.transferPageBl(),
+                            saveRequest.backgroupDomain(),
+                            saveRequest.listButton(),
+                            saveRequest.groupListDisplay()
+                    )).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类型错误");
+
+    }
+
+    /**
+     * 删除计划
+     *
+     * @param planNewId
+     * @return {@link Mono}<{@link RStatus}<{@link Long}>>
+     */
+    @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类型错误");
+    }
+
+    /**
+     * 计划-编辑回显详情
+     *
+     * @param planNewId
+     * @return
+     */
+    @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(),
+                                        saveRequest.listButton(),
+                                        Objects.nonNull(saveRequest.importDomain()) && !"".equals(saveRequest.importDomain().trim()) ? Integer.valueOf(saveRequest.importDomain()) : null,
+                                        Objects.nonNull(saveRequest.landingPageDomain()) && !"".equals(saveRequest.landingPageDomain().trim()) ? Integer.valueOf(saveRequest.landingPageDomain()) : null,
+
+                                        // saveRequest.landingPageDomain(),
+                                        Objects.nonNull(saveRequest.transferPageDomain()) && !"".equals(saveRequest.transferPageDomain().trim()) ? Integer.valueOf(saveRequest.transferPageDomain()) : null,
+
+                                        // saveRequest.transferPageDomain(),
+                                        saveRequest.transferPageBl(),
+                                        Objects.nonNull(saveRequest.backgroupDomain()) && !"".equals(saveRequest.backgroupDomain().trim()) ? Integer.valueOf(saveRequest.backgroupDomain()) : null,
+                                        saveRequest.groupListDisplay()
+
+                                        // saveRequest.backgroupDomain()
+                                );
+                                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("listening_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,
+                                        saveRequest.listButton(),
+                                        null,
+                                        null,
+                                        null,
+                                        null,
+                                        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类型错误");
+    }
+
+
+    /**
+     * 计划列表-下拉(查看自己创建的)(V2.0)
+     *
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link Paged}<{@link PlanNew}>>>
+     */
+    @PostMapping("planSelectSelf")
+    public Mono<RStatus<List<SelectPlanRes1>>> planSelectSelf(@RequestBody PosterTemSelectSelf request) {
+
+        if (Objects.isNull(request.getUserId())) {
+            request.setUserId(BaseContextHandler.getUserId());
+        }
+        Criteria criteria = Criteria.where("create_id").is(request.getUserId()); // poster_template_id
+        if (Objects.nonNull(request.getName()) && !request.getName().isEmpty()) {
+            criteria = criteria.and("name").like("%" + request.getName() + "%");
+        }
+        return getPlanSelect(criteria);
+    }
+
+
+    /**
+     * 计划列表-下拉
+     *
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link List}<{@link SelectPlanRes1}>>>
+     */
+    @PostMapping("planSelect")
+    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());
+        }
+        return getPlanSelect(criteria);
+    }
+
+    private Mono<RStatus<List<SelectPlanRes1>>> getPlanSelect( Criteria criteria) {
+        Mono<List<SelectPlanRes1>> listMono = template.select(Query.query(criteria), PlanNew.class).flatMap(fm -> {
+            SelectPlanRes1 selectPlanRes1 = new SelectPlanRes1();
+            selectPlanRes1.setName(fm.name());
+            selectPlanRes1.setType(1);
+            selectPlanRes1.setPlanNewId(fm.planNewId());
+            return Mono.just(selectPlanRes1);
+        }).collectList();
+        Mono<List<SelectPlanRes1>> listMono1 = template.select(Query.query(criteria), ListeningPlanNew.class).flatMap(fm -> {
+            SelectPlanRes1 selectPlanRes1 = new SelectPlanRes1();
+            selectPlanRes1.setName(fm.name());
+            selectPlanRes1.setType(2);
+            selectPlanRes1.setPlanNewId(fm.listeningPlanNewId());
+            return Mono.just(selectPlanRes1);
+        }).collectList();
+        Mono<List<SelectPlanRes1>> listMono2 = template.select(Query.query(criteria), PlanNewCommon.class).flatMap(fm -> {
+            SelectPlanRes1 selectPlanRes1 = new SelectPlanRes1();
+            selectPlanRes1.setName(fm.name());
+            selectPlanRes1.setType(3);
+            selectPlanRes1.setPlanNewId(fm.id());
+            return Mono.just(selectPlanRes1);
+        }).collectList();
+        Mono<List<SelectPlanRes1>> arrayListMono = Mono.zip(listMono, listMono1, listMono2).flatMap(f -> {
+            List<SelectPlanRes1> t1 = f.getT1();
+            List<SelectPlanRes1> t2 = f.getT2();
+            List<SelectPlanRes1> t3 = f.getT3();
+            ArrayList<SelectPlanRes1> objects = new ArrayList<>();
+            objects.addAll(t1);
+            objects.addAll(t2);
+            objects.addAll(t3);
+            return Mono.just(objects);
+        });
+        return RStatus.successList(arrayListMono);
+    }
+
+
+    /**
+     * 计划列表
+     *
+     * @param request request
+     * @return {@link Mono}<{@link RStatus}<{@link Paged}<{@link ListeningPlanNewRes2}>>>
+     */
+    @PostMapping("planList")
+    public Mono<RStatus<Paged<ListeningPlanNewRes2>>> page(@RequestBody PlanReqPage request) {
+        Criteria criteria = Criteria.empty(); // poster_template_id
+        if (Objects.nonNull(request.getCode()) && !request.getCode().trim().isEmpty()) {
+            criteria = criteria.and("code").like("%" + request.getCode() + "%");
+        }
+        if (Objects.nonNull(request.getName()) && !request.getName().trim().isEmpty()) {
+            criteria = criteria.and("name").like("%" + request.getName() + "%");
+        }
+        if (Objects.nonNull(request.getCreateUser()) && !request.getCreateUser().trim().isEmpty()) {
+            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());
+        }
+        if (Objects.nonNull(request.getGroupId()) && 0L != request.getGroupId()) {
+            criteria = criteria.and("group_id").is(request.getType());
+        }
+        if (2 == request.getType()) {
+            return listeningPlanService.page(request, criteria);
+        } else if (1 == request.getType()) {
+            return getType1(request, criteria);
+        } else {
+            return planServiceInterface.page(request, criteria);
+        }
+    }
+
+    private Mono<RStatus<Paged<ListeningPlanNewRes2>>> getType1(PlanReqPage request, Criteria criteria) {
+        Query query = Query.query(criteria);
+        int skip = (request.getPage() - 1) * request.getSize();
+        int limit = request.getSize();
+        Mono<Long> count = template.count(query, PlanNew.class);
+        Flux<PlanNew> created_at = template.select(Query.query(criteria)
+                .offset(skip)
+                .limit(limit)
+                .sort(Sort.by(Sort.Order.desc("created_at"))), PlanNew.class);
+        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();
+            List<ListeningPlanNewRes2> t2 = ff.getT2().stream().sorted(Comparator.comparing(ListeningPlanNewRes::getCreatedAt).reversed()).collect(Collectors.toList());
+            Paged<ListeningPlanNewRes2> planNewResPaged = new Paged<>(t1, t2, request.getPage(), request.getSize());
+            return Mono.just(planNewResPaged);
+        });
+        return RStatus.successList(pagedMono);
+    }
+}

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

@@ -0,0 +1,1013 @@
+package com.webflux.launchadmin.mysql.controller.planNew;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
+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.planNew.req.*;
+import com.webflux.launchadmin.mysql.controller.planNew.res.*;
+import com.webflux.launchadmin.mysql.entity.listening.ListeningPlanNew;
+import com.webflux.launchadmin.mysql.entity.planNew.*;
+import com.webflux.launchadmin.mysql.service.planNew.goGenerate.GoGenerateService;
+import com.webflux.launchadmin.mysql.service.planNew.ipAnalyze.IpAnalyzeServiceInterface;
+import com.webflux.launchadmin.mysql.service.planNew.structure.GoRequest;
+import com.webflux.launchadmin.mysql.service.planNew.structure.Item;
+import com.webflux.launchcommon.returnObj.RStatus;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+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.http.server.reactive.ServerHttpRequest;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+import java.net.InetSocketAddress;
+import java.net.URLEncoder;
+import java.net.http.HttpRequest;
+import java.nio.charset.StandardCharsets;
+import java.time.ZonedDateTime;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+
+/**
+ * 计划-H5
+ * @author lw12420
+ * @date 2024/05/21
+ */
+@RestController
+@RequestMapping("out/planNew")
+@Slf4j
+public class PlanNewOutController {
+    @Resource
+    private R2dbcEntityTemplate template;
+
+    @Resource
+    private GoGenerateService goGenerateService;
+
+    @Resource
+    private IpAnalyzeServiceInterface ipAnalyzeServiceInterface;
+
+
+
+    private static final ConcurrentHashMap<String,Integer> map = new ConcurrentHashMap<String,Integer>();
+
+    //清空用户Map数据
+    @Scheduled(cron="1 1 4 * * ?")
+    public void clearUserContextMap(){
+        log.info("清空计划-H5用户Map数据》》》》》》》》》》》》》》》》》》》》》》开始");
+        map.clear();
+        log.info("清空计划-H5用户Map数据》》》》》》》》》》》》》》》》》》》》》》 结束");
+    }
+
+    /**
+     * 获取二维码缓存信息
+     * @param id
+     * @return {@link Mono}<{@link RStatus}<{@link QrcodeInfo}>>
+     */
+    @GetMapping("getQrcode/{id}")
+    public Mono<RStatus<QrcodeInfo>> getQrcode(@PathVariable("id") Long id){
+        Mono<QrcodeInfo> qrcodeInfoMono = template.selectOne(Query.query(Criteria.where("id").is(id)), QrcodeInfo.class)
+                .switchIfEmpty(Mono.error(new BaseException("id异常 查询结果为空")))
+                .onErrorResume(throwable -> Mono.error(new BaseException("查询异常::::" + throwable.getMessage())));
+        return RStatus.success(qrcodeInfoMono);
+    }
+    /**
+     *通过 code and type 查询 domain
+     * @param code
+     * @param type
+     * @return {@link Mono}<{@link RStatus}<{@link DomainSelectRes}>>
+     */
+    @GetMapping("domain/select")
+    public Mono<RStatus<DomainSelectRes>> domainSelect(@RequestParam("code") String code,@RequestParam("type") String type ,@RequestParam("typePlan") Integer typePlan ){
+        if (1 == typePlan) {
+            Mono<PlanNew> code1 = template
+                    .selectOne(Query.query(Criteria.where("code").is(code)), PlanNew.class)
+                    .switchIfEmpty(Mono.error(new BaseException("计划code异常 返回结果为空"))) //Mono.error(new BaseException("查询海报模版 id:"+f.posterTemplateId()+"=>空"))
+                    .onErrorResume(throwable -> Mono.error(new Exception(  throwable.getMessage())));
+            Mono<DomainSelectRes> domainSelectResMono1 = code1.flatMap(f -> {
+                Mono<String> stringMono;
+                if (f.transferPageBl() == 1 && Objects.nonNull(f.transferPageDomain())) {
+                    stringMono = template.select(Query.query(Criteria
+                            .where("group_type_id").is(f.transferPageDomain())
+                            .and("status").is(1)
+                            .and("type").is(5)
+                            .and("deleted_at").isNull()), DomainSelect.class)
+                            .switchIfEmpty(Mono.error(new BaseException("transferPageDomain 域名查詢為空 group_type_id:::" + f.transferPageDomain())))
+                            .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()))).collectList().flatMap(fff -> {
+                                if (!fff.isEmpty()) {
+                                    DomainSelect domainSelect = fff.get(RandomUtil.randomInt(0, fff.size()));
+                                    String string = RandomUtil.randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6);
+                                    String domain1 = domainSelect.domain();
+                                    return Mono.just(string+"."+domain1);
+
+                                } else {
+                                    throw new BaseException("transferPageDomain 中轉域名查詢為空 group_type_id:::" + f.transferPageDomain());
+                                }
+                            });
+                }else {
+                    stringMono = Mono.just(" ");
+                }
+                Mono<String> stringMono1;
+                if ( Objects.nonNull(f.backgroupDomain()) && !"".equals(f.backgroupDomain().trim()) ) {
+                    stringMono1 = template.select(Query.query(Criteria
+                            .where("group_type_id").is(f.backgroupDomain())
+                            .and("status").is(1)
+                            .and("type").is(4)
+                            .and("deleted_at").isNull()), DomainSelect.class)
+                            .switchIfEmpty(Mono.error(new BaseException("backgroupDomain 域名查詢為空 group_type_id" + f.backgroupDomain())))
+                            .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()))).collectList().flatMap(fff -> {
+                                if (!fff.isEmpty()) {
+                                    DomainSelect domainSelect = fff.get(RandomUtil.randomInt(0, fff.size()));
+                                    String string = RandomUtil.randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6);
+                                    String domain1 = domainSelect.domain();
+                                    return Mono.just(string+"."+domain1);
+                                } else {
+                                    throw new BaseException("backgroupDomain 背景域名查詢為空 group_type_id" + f.backgroupDomain());
+                                }
+                            });
+                }else {
+                    stringMono1 =  Mono.just(" ");
+                }
+                Mono<String> stringMono2 = template.select(Query.query(Criteria.where("group_type_id").is(f.landingPageDomain())
+                        .and("status").is(1).and("type").is(type).and("deleted_at").isNull()), DomainSelect.class)
+                        .switchIfEmpty(Mono.error(new BaseException("查询domain 返回结果为空")))
+                        .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()))).collectList().flatMap(fm -> {
+                          //  DomainSelectRes domainSelectRes = new DomainSelectRes();
+                            int i = RandomUtil.randomInt(0, fm.size());
+                            String domain = fm.get(i).domain();
+                            String string = RandomUtil.randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6);
+                          //  domainSelectRes.setBackgroupDomain(f.backgroupDomain());
+                         //   domainSelectRes.setTransferPageDomain(f.transferPageDomain());
+                           // domainSelectRes.setTransferPageBl(f.transferPageBl());
+                           // domainSelectRes.setDomain(string + "." + domain);
+                          //  domainSelectRes.setPath("");
+                          //  domainSelectRes.setUnique(IdUtil.fastSimpleUUID());
+                            return Mono.just(string + "." + domain);
+                        });
+               return Mono.zip(stringMono2,stringMono1,stringMono).flatMap(fff->{
+                    DomainSelectRes domainSelectRes = new DomainSelectRes();
+                    domainSelectRes.setDomain(fff.getT1());
+                    domainSelectRes.setPath("");
+                    domainSelectRes.setTransferPageBl(f.transferPageBl());
+                    domainSelectRes.setBackgroupDomain(fff.getT2());
+                    domainSelectRes.setTransferPageDomain(fff.getT3());
+                    domainSelectRes.setUnique(IdUtil.fastSimpleUUID());
+                    return Mono.just(domainSelectRes);
+                });
+            });
+            return RStatus.success(domainSelectResMono1);
+        }else  if(2==typePlan){
+            Mono<ListeningPlanNew> code1 = template.selectOne(Query.query(Criteria.where("code").is(code)), ListeningPlanNew.class)
+                    .switchIfEmpty(Mono.error(new BaseException("计划code异常 返回结果为空"))) //Mono.error(new BaseException("查询海报模版 id:"+f.posterTemplateId()+"=>空"))
+                    .onErrorResume(throwable -> Mono.error(new Exception(  throwable.getMessage())));
+            Mono<DomainSelectRes> domainSelectResMono1 = code1.flatMap(f -> template.select(Query.query(Criteria.where("group_type_id").is(f.groupId())
+                    .and("status").is(1).and("type").is(type).and("deleted_at").isNull()), DomainSelect.class)
+                    .switchIfEmpty(Mono.error(new BaseException("查询domain 返回结果为空")))
+                    .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()))).collectList().flatMap(fm -> {
+                        DomainSelectRes domainSelectRes = new DomainSelectRes();
+                        int i = RandomUtil.randomInt(0, fm.size());
+                        String domain = fm.get(i).domain();
+                        String string = RandomUtil.randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6);
+                        domainSelectRes.setDomain(string+"."+domain);
+                        domainSelectRes.setPath("");
+                        domainSelectRes.setUnique(IdUtil.fastSimpleUUID());
+                        return Mono.just(domainSelectRes);
+                    }));
+            return RStatus.success(domainSelectResMono1);
+        }
+        throw new BaseException("typePlan 类型错误");
+
+
+    }
+    /**
+     * 列表返回images(列表内容),shareQrurl(背景组) ,baiduDot,retAudio
+     * Mono<RStatus<DataListsKefu>>
+     *     //  return Mono.just(new Audio(null,null,null,null,null,null,null,null));
+     */
+
+    @PostMapping("kefuList")
+    public Mono<RStatus<DataListsKefu>> kefuList(@RequestBody KefuRequest request){
+        Mono<PlanNew> code = template.selectOne(Query.query(Criteria.where("code").is(request.getCode())), PlanNew.class)
+                .switchIfEmpty(Mono.error(new BaseException("code查询返回结构为空"))) //Mono.error(new BaseException("查询海报模版 id:"+f.posterTemplateId()+"=>空"))
+                .onErrorResume(throwable -> Mono.error(new Exception("通过code查询计划异常::" + throwable.getMessage())));
+        Mono<DataListsKefu> dataListsKefuMono = code.flatMap(planNew -> {
+            Mono<List<Image>> image = template.select(Query.query(Criteria.where("type").is(5)
+                    .and("deleted_at").isNull()
+                    .and("group_type_id").is(planNew.groupId())), Image.class)
+                    .collectList()
+                    .switchIfEmpty(Mono.error(new BaseException(StrUtil.format("通过计划groupId:{}查询Image返回结构为空", planNew.groupId()))))
+                    .onErrorResume(throwable ->
+                            Mono.error(new Exception(StrUtil.format("通过计划groupId:{}查询Image返回结果error:{}", planNew.groupId(), throwable.getMessage()))));
+            Mono<List<Material>> text = template.select(Query.query(Criteria.where("type").is(11)
+                            .and("group_type_id").is(planNew.groupId())
+                            .and("deleted_at").isNull()), Material.class)
+                    .switchIfEmpty(Mono.error(new BaseException(StrUtil.format("通过计划groupId:{}查询Material返回结构为空", planNew.groupId()))))
+                    .onErrorResume(throwable ->
+                            Mono.error(new Exception(StrUtil.format("通过计划groupId:{}查询Material返回结果error:{}", planNew.groupId(), throwable.getMessage()))))
+                    .collectList();
+            Mono<List<H5ImageAndText>> arrayListMono = Mono.zip(Mono.just(planNew), image, text).flatMap(f -> {
+                //H5ImageAndText
+                Integer integer = f.getT1().pageShow();//群数量
+                //List<Domain> t2 = f.getT2();
+                List<Image> t3 = f.getT2();
+                List<Material> t4 = f.getT3();
+                if (t3.size() < integer || 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 -> {
+                    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());
+                    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());
+                    //Image image1 = t3.get(RandomUtil.randomInt(0, t3.size()));
+                    //Domain domain1 = t2.get(RandomUtil.randomInt(0,t2.size()));
+                    //Material material = t4.get(RandomUtil.randomInt(0, t4.size()));
+                    H5ImageAndText h5ImageAndText = new H5ImageAndText();
+                    h5ImageAndText.setImage(image1.image());
+                    //h5ImageAndText.setDomain(domain1.domain());
+                    h5ImageAndText.setName(material.content());
+                    h5ImageAndText.setRemark(material.remark());
+                    h5ImageAndTexts.add(h5ImageAndText);
+                });
+                return Mono.just(h5ImageAndTexts);
+            });
+            Mono<List<BackgroupImageItem>> group_id = Mono.just(planNew)
+                    .filter(ft -> Objects.nonNull(ft.backgroundGroupIdNewAdd()))
+                    .flatMap(plan ->
+                            template.select(Query.query(Criteria.where("group_id")
+                            .is(plan.backgroundGroupIdNewAdd())), BackgroupImageItem.class).collectList())
+                    .switchIfEmpty(Mono.just(List.of()));
+            Mono<Audio> retAudioId = Mono.just(planNew).flatMap(plan -> {
+                if(Objects.nonNull(plan.retAudioId())){
+                   return template.selectOne(Query.query(Criteria.where("id").is(plan.retAudioId())), Audio.class)
+                           .switchIfEmpty(Mono.error(new BaseException(StrUtil.format("通过计划retAudioId:{}查询音频为空",plan.retAudioId()))))
+                           .onErrorResume(throwable -> Mono.error(new BaseException(StrUtil.format("通过计划retAudioId:{}查询音频Error::",plan.retAudioId(),throwable.getMessage()))));
+                }else {
+                    return Mono.just(new Audio(null,null,null,null,null,null,null,null));
+                }
+            });
+            Mono<DataListsKefu> dataListsMono = Mono.zip(Mono.just(planNew), group_id, retAudioId, arrayListMono).flatMap(f -> {
+                DataListsKefu dataLists = new DataListsKefu();
+                dataLists.setPlanNew(f.getT1());
+                dataLists.setBaiduDot(f.getT1().baiduDot());
+                List<BackgroupImageItem> t2 = f.getT2();
+                if (!t2.isEmpty()) {
+                    List<String> collect = t2.stream().map(BackgroupImageItem::image).collect(Collectors.toList());
+                    dataLists.setShareQrurl(collect);
+                }
+                if(Objects.nonNull(f.getT3().id())){
+                    dataLists.setRetAudio(f.getT3());
+                }
+                dataLists.setImages(f.getT4());
+                return Mono.just(dataLists);
+            });
+            return dataListsMono;
+        });
+        // //类型 1素材分类2清水分类
+      //  Mono<List<Domain>> domain = code.flatMap(plan -> template.select(Query.query(Criteria.where("group_type").is(1).and("deleted_at").isNull()), Domain.class).collectList());
+      //  Mono<List<Image>> image = template.select(Query.query(Criteria.where("type").is(5).and("deleted_at").isNull()), Image.class).collectList();
+      //  Mono<List<Material>> text = template.select(Query.query(Criteria.where("type").is(11).and("deleted_at").isNull()), Material.class).collectList();
+
+//        Mono<List<BackgroupImageItem>> group_id = code.filter(ft->Objects.nonNull(ft.backgroundGroupIdNewAdd())).flatMap(plan -> template
+//                .select(Query.query(Criteria.where("group_id")
+//                        .is(plan.backgroundGroupIdNewAdd())), BackgroupImageItem.class).collectList())
+//                .switchIfEmpty(Mono.just(List.of()));
+
+        return RStatus.successList(dataListsKefuMono);
+    }
+    /**
+     * h5-通过code (第一个接口)
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link DataLists}>>
+     */
+    @PostMapping("hfoInfo")
+    public Mono<RStatus<DataLists>> hfoInfo(@RequestBody HfoRequest request, ServerWebExchange exchange){
+        ServerHttpRequest httpRequest = exchange.getRequest();
+        InetSocketAddress remoteAddress = httpRequest.getRemoteAddress();
+        String ipAddress;
+        if (remoteAddress != null) {
+            ipAddress = remoteAddress.getAddress().getHostAddress();
+        } else {
+            ipAddress = null;
+        }
+
+        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<DataLists> dataListsMono1 = code0.flatMap(planNew -> {
+            Mono<PlanNew> code = Mono.just(planNew);
+            Long group_type_id ; //.and("group_type_id").is(group_type_id)
+            if (Objects.isNull(request.getWx_user_id()) || "".equals(request.getWx_user_id())) {
+                group_type_id=planNew.groupId();
+            }else {
+                group_type_id=planNew.groupIdQs();
+            }
+            Mono<List<Domain>> domain = code.flatMap(plan -> template.select(Query.query(Criteria.where("group_type").is(1)
+                    .and("deleted_at").isNull()), Domain.class).onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()+"6"))).collectList());
+            // //类型 1素材分类2清水分类
+            Criteria criteria = Criteria.where("type")
+                    .is(1).and("deleted_at").isNull()
+                    .and("group_type_id").is(group_type_id);
+            if(planNew.pageLine()==1){
+                criteria =criteria.and("size_type").is(2);
+            }else {
+                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")))
+                    .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")))
+                    .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")))
+                        .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")));
+                            }
+                        }).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();
+                    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());
+                    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());
+                    String content = material.content();
+                    // 解析ip归属地
+                    if (StrUtil.isNotBlank(ipAddress)) {
+                        JSONObject ipInfo = ipAnalyzeServiceInterface.getIpInfo(ipAddress);
+                        if (null != ipInfo) {
+                            String city = ipInfo.getStr("city");
+                            if (StrUtil.isNotBlank(city)) {
+                                content = city + content;
+                            } else {
+                                String province = ipInfo.getStr("region");
+                                if (StrUtil.isNotBlank(province)) {
+                                    content = province + content;
+                                }
+                            }
+                        }
+                    }
+                    h5ImageAndText.setName(content);
+                    h5ImageAndText.setRemark(material.remark());
+                    h5ImageAndTexts.add(h5ImageAndText);
+                });
+                return Mono.just(h5ImageAndTexts);
+            });
+
+            Mono<Audio> listAudio = code.flatMap(plan ->{
+                if (Objects.isNull(plan.listAudioId())) {
+                    return Mono.just(new Audio(null,null,null,null,null,null,null,null));
+                }else {
+                    return  template.selectOne(
+                            Query.query(Criteria.where("id").is(plan.listAudioId()).and("deleted_at").isNull()),
+                            Audio.class);
+                } }
+            ).onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()+"1")));
+            Mono<Audio> retAudioId = code.flatMap(plan -> template.selectOne(Query.query(Criteria.where("id")
+                    .is(plan.retAudioId()).and("deleted_at").isNull()), Audio.class)).onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()+"2")));
+            Mono<ReturnLoop> returnLoop = code.flatMap(plan -> {
+                if (Objects.isNull(plan.returnLoopId())) {
+                    return Mono.just(getReturnLoop());
+                } else {
+                    return template.selectOne(Query.query(Criteria.where("id").is(plan.returnLoopId()).and("deleted_at").isNull()), ReturnLoop.class).onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()+"3")));
+                }
+            }).switchIfEmpty(Mono.just(getReturnLoop()));
+            Mono<List<Ad>> adtop = template.select(Query.query(Criteria.where("type").is(1).and("deleted_at").isNull()), Ad.class).onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()+"4"))).collectList();////广告类型1顶部2底部3返回4安卓,ios的返回
+            Mono<List<Ad>> bottom = template.select(Query.query(Criteria.where("type").is(2).and("deleted_at").isNull()), Ad.class).onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()+"5"))).collectList();
+
+
+            Mono<DataLists> dataListsMono = Mono.zip(code, listAudio, retAudioId, returnLoop, arrayListMono, adtop, bottom, wx_user_id).flatMap(f -> {
+                DataLists dataLists = new DataLists();
+                dataLists.setPlanNew(f.getT1());
+                dataLists.setListButton(f.getT1().listButton());
+                if (Objects.nonNull(f.getT2().id())) {
+                    dataLists.setListAudio(f.getT2());
+                }
+                dataLists.setRetAudio(f.getT3());
+                if (-1 != f.getT4().id()) {
+                    dataLists.setReturnLoop(f.getT4());
+                } else {
+                    dataLists.setReturnLoop(null);
+                }
+                dataLists.setImages(f.getT5());
+                if(  Objects.isNull(request.getWx_user_id()) || "".equals(request.getWx_user_id())){
+                    dataLists.setIsRet(-1);
+                }else {
+                    if (f.getT8().num() >= 4) {
+                        dataLists.setIsRet(1);
+                    }else{
+                        dataLists.setIsRet(-1);
+                    }
+                }
+                if (f.getT1().topAdvBl() == 1) {
+                    List<Ad> ads = f.getT6().subList(0, f.getT1().topAdvNum());
+                    dataLists.setTopAd(ads);
+                }
+                if (f.getT1().bottomAdvBl() == 1) {
+                    List<Ad> ads = f.getT7().subList(0, f.getT1().bottomAdvNum());
+                    dataLists.setBottomAd(ads);
+                }
+//                Mono<String> stringMono;
+//                if (f.getT1().transferPageBl() == 1 && Objects.nonNull(f.getT1().transferPageDomain())) {
+//                   stringMono = template.select(Query.query(Criteria
+//                            .where("group_type_id").is(f.getT1().transferPageDomain())
+//                            .and("status").is(1)
+//                            .and("type").is(5)
+//                            .and("deleted_at").isNull()), DomainSelect.class)
+//                            .switchIfEmpty(Mono.error(new BaseException("transferPageDomain 域名查詢為空 group_type_id:::" + f.getT1().transferPageDomain())))
+//                            .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()))).collectList().flatMap(fff -> {
+//                                if (!fff.isEmpty()) {
+//                                    DomainSelect domainSelect = fff.get(RandomUtil.randomInt(0, fff.size()));
+//                                    String string = RandomUtil.randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6);
+//                                    String domain1 = domainSelect.domain();
+//                                    return Mono.just(string+"."+domain1);
+//
+//                                } else {
+//                                    throw new BaseException("transferPageDomain 中轉域名查詢為空 group_type_id:::" + f.getT1().transferPageDomain());
+//                                }
+//                            });
+//                }else {
+//                    stringMono = Mono.just(" ");
+//                }
+//                Mono<String> stringMono1;
+//                if ( Objects.nonNull(f.getT1().backgroupDomain()) && !"".equals(f.getT1().backgroupDomain().trim()) ) {
+//                    stringMono1 = template.select(Query.query(Criteria
+//                            .where("group_type_id").is(f.getT1().backgroupDomain())
+//                            .and("status").is(1)
+//                            .and("type").is(4)
+//                            .and("deleted_at").isNull()), DomainSelect.class)
+//                            .switchIfEmpty(Mono.error(new BaseException("backgroupDomain 域名查詢為空 group_type_id" + f.getT1().backgroupDomain())))
+//                            .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage()))).collectList().flatMap(fff -> {
+//                                if (!fff.isEmpty()) {
+//                                    DomainSelect domainSelect = fff.get(RandomUtil.randomInt(0, fff.size()));
+//                                    String string = RandomUtil.randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6);
+//                                    String domain1 = domainSelect.domain();
+//                                    return Mono.just(string+"."+domain1);
+//                                } else {
+//                                    throw new BaseException("backgroupDomain 背景域名查詢為空 group_type_id" + f.getT1().backgroupDomain());
+//                                }
+//                            });
+//                }else {
+//                    stringMono1 =  Mono.just(" ");
+//                }
+//                return   Mono.zip(stringMono,stringMono1,Mono.just(dataLists)).flatMap(fff->{
+//                    DataLists t3 = fff.getT3();
+//                    t3.setTransferPageBl(f.getT1().transferPageBl());
+//                    t3.setTransferPageDomain(fff.getT1());
+//                    t3.setBackgroupDomain(fff.getT2());
+//                    return Mono.just(t3);
+//                });
+                return Mono.just(dataLists);
+            });
+            return dataListsMono;
+        });
+        return RStatus.successList(dataListsMono1);
+    }
+
+
+    private ReturnLoop getReturnLoop() {
+        return new ReturnLoop(-1L, null, null, null, null, null, null, null, null, null, null, null, null, null);
+    }
+
+
+    /**
+     * h5-通过code (第二个接口)
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link DataLists}>>
+     */
+    @PostMapping("hftInfo")
+    public Mono<RStatus<DataLists0>> hftInfo(@RequestBody HftRequest 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<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值不为空则使用清水分类)
+            Mono<StringBuilder> stringBuilderMono;
+            if (Objects.nonNull(ftmp.redirectType()) && ftmp.redirectType() == 2) {
+                 stringBuilderMono =  goGenerateService.byPlanNewIdGetUrl(ftmp.redirectPlanId(),
+                         Objects.nonNull(request.getWx_user_id()) && !"".equals(request.getWx_user_id()));
+            }else {
+                stringBuilderMono =Mono.just(new StringBuilder(ftmp.link()));
+            }
+            Mono<PlanNew> code = Mono.just(ftmp);
+            return  Mono.zip(code, getPoster_template_id(code), getPoster(code), getPlanNewBackgroupPoster(code),getEwm(request, code),stringBuilderMono).flatMap(f -> {
+                DataLists0 dataLists0 = new DataLists0();
+                dataLists0.setSpare(f.getT5().toString());
+                dataLists0.setRedirectType(f.getT1().redirectType());
+                dataLists0.setPlanNew(f.getT1());
+                dataLists0.setGroupListDisplay(f.getT1().groupListDisplay());
+                dataLists0.setPosterTemplate(f.getT2());
+                List<Poster> t3 = f.getT3();
+                if(t3.size()!=0){
+                    if (t3.size() <= request.getUserVisits()) {
+                        dataLists0.setPoster(t3.getLast());
+                    }else {
+                        dataLists0.setPoster(t3.get(request.getUserVisits()));
+                    }
+                }
+                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());
+                    if(Objects.nonNull(qs) && !qs.isEmpty()){
+                        if (qs.size() <= request.getUserVisits()) {
+                            Integer userVisits = request.getUserVisits();
+                            int v =userVisits%qs.size();
+                            dataLists0.setQsSetting(qs.get(v));
+                            if("".equals(f.getT6().toString())){
+                                throw new BaseException("计划链接 查询匹配域名为空");
+                            }
+                            dataLists0.setLink(f.getT6().toString());
+                        }else {
+                            dataLists0.setQsSetting(qs.get(request.getUserVisits()));
+                            dataLists0.setLink(null);
+                        }
+                    }
+                    PlanNewBackgroupPoster qsSetting = dataLists0.getQsSetting();
+                    if(Objects.nonNull(qsSetting)){
+                        dataLists0.setLimitTime(qsSetting.limitTime());
+                        dataLists0.setLimitTimeRemark(qsSetting.limitTimeRemark());
+                    }
+                }else {
+                    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();
+                            int v =userVisits%fx.size();
+                            dataLists0.setFxSetting(fx.get(v));
+                            if("".equals(f.getT6().toString())){
+                                throw new BaseException("计划链接 查询匹配域名为空");
+                            }
+                            dataLists0.setLink(f.getT6().toString());
+                        }else {
+                            dataLists0.setLink(null);
+                            dataLists0.setFxSetting(fx.get(request.getUserVisits()));
+                        }
+                    }
+                    PlanNewBackgroupPoster fxSetting = dataLists0.getFxSetting();
+                    if(Objects.nonNull(fxSetting)){
+                        dataLists0.setLimitTime(fxSetting.limitTime());
+                        dataLists0.setLimitTimeRemark(fxSetting.limitTimeRemark());
+                    }
+                }
+                return Mono.just(dataLists0);
+            });
+        });
+
+        Mono<DataLists0> dataLists0Mono1 = setEndData(request, setFmV(request, setAudioV(request, dataLists0Mono)));
+        return RStatus.successList(dataLists0Mono1);
+    }
+//设置二维码 生成图片
+    private Mono<DataLists0> setEndData(HftRequest request, Mono<DataLists0> dataLists0Mono2) {
+        Mono<DataLists0> dataLists0Mono1 = dataLists0Mono2.flatMap(fm -> {
+            Poster poster = fm.getPoster();
+            if (Objects.isNull(poster)) {
+                return Mono.just(fm);
+            }
+            String posterTemplate = poster.posterTemplate();
+            GoRequest goRequest ;
+            if (Objects.nonNull(request.getWx_user_id()) && !"".equals(request.getWx_user_id())) {
+                PlanNewBackgroupPoster qsSetting = fm.getQsSetting();
+                goRequest = setNameVal(posterTemplate, qsSetting,fm.getSpare());
+            } else {
+                PlanNewBackgroupPoster fxSetting = fm.getFxSetting();
+                goRequest = setNameVal(posterTemplate, fxSetting,fm.getSpare());
+            }
+            if (Objects.nonNull(goRequest) && Objects.nonNull(goRequest.getItem())) {
+                Optional<Item> first = goRequest.getItem().stream()
+                        .filter(ff -> "title".equals(ff.getT()) && ff.getIsRandom())
+                        .findFirst();
+                first.ifPresent(item -> fm.setGroupTitle(item.getV()));
+                Optional<Item> first1 = goRequest.getItem().stream().filter(ff -> "cover".equals(ff.getT()) && ff.getIsRandom()).findFirst();
+                first1.ifPresent(item -> fm.setGroupHeadUrl(item.getV()));
+            }
+            if (Objects.isNull(goRequest)) {
+                throw  new BaseException("isNull(goRequest) setEndData()");
+            }
+            QrcodeInfo stringBuilder = getQrcodeInfo(goRequest);
+            Mono<QrcodeInfo> qrcodeInfoMono = template.insert(stringBuilder)
+                    .onErrorResume(throwable -> Mono.error(new BaseException("插入QrcodeInfo异常::::" + throwable.getMessage())));
+//            if(Objects.nonNull(fm.getPlanNew().groupListDisplay()) && fm.getPlanNew().groupListDisplay()==1){
+//                qrcodeInfoMono = template.insert(stringBuilder)
+//                                .onErrorResume(throwable -> Mono.error(new BaseException("插入QrcodeInfo异常::::" + throwable.getMessage())));
+//            }else {
+//                qrcodeInfoMono = Mono.just(stringBuilder);
+//            }
+           return Mono.zip(qrcodeInfoMono,Mono.just(goRequest),Mono.just(fm)).flatMap(f9->{
+                GoRequest goRequest2 = f9.getT2();
+                if (Objects.nonNull(f9.getT1().id())) {
+                    goRequest2.getItem().stream().filter(f1 -> "qrcode".equals(f1.getT())).forEach(fe->{
+                        if (Objects.nonNull(fe.getV())) {
+                            if (fe.getV().contains("?")){
+                                String qrcode = fe.getV() + "&id=" + f9.getT1().id();
+                                fe.setV(qrcode);
+                            }else{
+                                String qrcode = fe.getV() + "?id=" + f9.getT1().id();
+                                fe.setV(qrcode);
+                            }
+                        }
+                    });
+                }
+                DataLists0 fm3 = f9.getT3();
+                String ret = goGenerateService.goGenerate(JSONUtil.toJsonStr(goRequest2));
+                if (Objects.nonNull(ret)) {
+                    JSONObject jsonObject1;
+                    try {
+                        jsonObject1 =  JSONUtil.parseObj(ret);
+                    }catch (Exception e){
+                        throw new BaseException(e.getMessage() +"---"+JSONUtil.parseObj(goRequest2));
+                    }
+                    if (jsonObject1.containsKey("code")
+                            && jsonObject1.get("code", Integer.class) == 0
+                            && jsonObject1.containsKey("data")) {
+                        JSONObject data = jsonObject1.get("data", JSONObject.class);
+                        if (data.containsKey("Url")) {
+                            String url = data.get("Url", String.class);
+                            if (Objects.nonNull(request.getWx_user_id()) && !"".equals(request.getWx_user_id())) {
+                                fm3.setQsGenerateImagesUrl(url);
+                            } else {
+                                fm3.setFxGenerateImagesUrl(url);
+                            }
+                        }
+                    }
+                }
+                return Mono.just(fm3);
+            });
+        });
+        return dataLists0Mono1;
+    }
+    private QrcodeInfo getQrcodeInfo(GoRequest goRequest)  {
+        Optional<Item> first = goRequest.getItem().stream().filter(ff -> "cover".equals(ff.getT()) ).findFirst();
+        Optional<Item> first3 = goRequest.getItem().stream().filter(ff -> "title".equals(ff.getT())).findFirst();
+        QrcodeInfo qrcodeInfo = new QrcodeInfo(null,first.isPresent()?first.get().getV():"",first3.isPresent()?first3.get().getV():"");
+        return qrcodeInfo;
+    }
+    // 设置封面等
+    private Mono<DataLists0> setFmV(HftRequest request, Mono<DataLists0> zip) {
+        Mono<DataLists0> dataLists0Mono2 = zip.flatMap(fm -> {
+            Poster poster = fm.getPoster();
+            if (Objects.isNull(poster)) {
+                return Mono.just(fm);
+            }
+            String posterTemplate = poster.posterTemplate();
+            JSONObject jsonObject ;
+            try {
+                jsonObject = JSONUtil.parseObj(posterTemplate);
+            }catch (Exception e){
+                throw new BaseException(e.getMessage() +"---"+posterTemplate);
+            }
+            //JSONObject jsonObject = JSONUtil.parseObj(posterTemplate);
+            GoRequest goRequest = new GoRequest();
+            BeanUtil.copyProperties(jsonObject, goRequest);
+
+            Mono<String> outTemPoster;
+            if (Objects.nonNull(request.getWx_user_id()) && !"".equals(request.getWx_user_id())) {
+                Long aLong = fm.getPlanNew().groupIdQs();
+                outTemPoster = goGenerateService.getOutTemPosterQs(goRequest,
+                       // goGenerateService.getStringBuilderMono(goRequest)
+                        goGenerateService.setCusqrcodeSetV(goRequest),
+                        aLong);
+            }else {
+                Long aLong = fm.getPlanNew().groupId();
+                outTemPoster = goGenerateService.getOutTemPosterYx(goRequest,
+                        //goGenerateService.getStringBuilderMono(goRequest),
+                        goGenerateService.setCusqrcodeSetV(goRequest),
+                        aLong);
+            }
+            return Mono.zip(Mono.just(fm), outTemPoster, (a, b) -> {
+                Poster poster1 = new Poster(poster.posterId(),
+                        poster.posterTemplateId(),
+                        b,
+                        poster.createUser(),
+                        poster.createId(),
+                        poster.createdAt(),
+                        poster.updatedAt(),
+                        poster.generateImagesJson(),
+                        poster.generateImagesUrl());
+                a.setPoster(poster1);
+                return a;
+            });
+        });
+        return dataLists0Mono2;
+    }
+
+    //音频
+    private Mono<DataLists0> setAudioV(HftRequest request, Mono<DataLists0> dataLists0Mono) {
+        Mono<DataLists0> zip = dataLists0Mono.flatMap(f -> {
+            Mono<Audio> id = null;
+            if (Objects.nonNull(request.getWx_user_id()) && !"".equals(request.getWx_user_id())) {
+                PlanNewBackgroupPoster qsSetting = f.getQsSetting();
+                if (Objects.nonNull(qsSetting) && Objects.nonNull(qsSetting.audioId()) && 0 != qsSetting.audioId()) {
+                    id = template.selectOne(Query.query(Criteria.where("id").is(qsSetting.audioId()).and("deleted_at").isNull()), Audio.class);
+                }
+            } else {
+                PlanNewBackgroupPoster fxSetting = f.getFxSetting();
+                if (Objects.nonNull(fxSetting) && Objects.nonNull(fxSetting.audioId()) && 0 != fxSetting.audioId()) {
+                    id = template.selectOne(Query.query(Criteria.where("id").is(fxSetting.audioId()).and("deleted_at").isNull()), Audio.class);
+                }
+            }
+            if (Objects.isNull(id)) {
+               // id = template.selectOne(Query.query(Criteria.where("id").is(f.getPlanNew().retAudioId())), Audio.class);
+                return Mono.just(f);
+            }
+            return Mono.zip(Mono.just(f), id, (a, b) -> {
+                a.setAudio(b);
+                return a;
+            });
+        });
+        return zip;
+    }
+
+    // //+二维码
+    private Mono<StringBuilder> getEwm(HftRequest request, Mono<PlanNew> code) {
+     //   Mono<StringBuilder> stringBuilderMono ;
+//        if (Objects.nonNull(request.getWx_user_id()) && !"".equals(request.getWx_user_id())) {
+//            stringBuilderMono = goGenerateService.getStringBuilderMonoQs(code);
+//        }else{
+//            stringBuilderMono =  goGenerateService.getStringBuilderMonoYx(code);
+//        }
+        return  goGenerateService.getOutImportDomain(code);
+    }
+
+    private Mono<List<PlanNewBackgroupPoster>> getPlanNewBackgroupPoster(Mono<PlanNew> code) {
+        return code.flatMap(plan -> template.select(Query.query(Criteria.where("plan_new_id")
+                .is(plan.planNewId())).sort(Sort.by(Sort.Order.asc("idx"))), PlanNewBackgroupPoster.class)
+                .collectList());
+    }
+
+    private Mono<List<Poster>> getPoster(Mono<PlanNew> 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());
+    }
+
+    private Mono<PosterTemplate> getPoster_template_id(Mono<PlanNew> code) {
+        return code.flatMap(plan -> template.selectOne(Query.query(Criteria.where("poster_template_id")
+                .is(plan.posterTemplateId())), PosterTemplate.class));
+    }
+    private StringBuilder getStringBuilder(GoRequest goRequest) {
+        Optional<Item> first = goRequest.getItem().stream().filter(ff -> "cover".equals(ff.getT()) ).findFirst();
+        Optional<Item> first3 = goRequest.getItem().stream().filter(ff -> "title".equals(ff.getT())).findFirst();
+        StringBuilder stringBuilder = new StringBuilder("&groupHeadUrl=");
+        stringBuilder.append(first.isPresent()?first.get().getV():"");
+        stringBuilder.append("&groupTitle=");
+        String encodedParam ="";
+        if(first3.isPresent() &&Objects.nonNull(first3.get().getV())){
+            try {
+                encodedParam = URLEncoder.encode(first3.get().getV(), StandardCharsets.UTF_8.toString());
+            }catch (Exception e){
+                throw new BaseException("URLEncoder Error"+e.getMessage());
+            }
+        }
+        stringBuilder.append(first3.isPresent()?encodedParam:"");
+        return stringBuilder;
+    }
+//qrcode 二维码设置
+    private GoRequest setNameVal(String posterTemplate, PlanNewBackgroupPoster qsSetting,String spare) {
+        JSONObject jsonObject ;
+        try {
+             jsonObject =  JSONUtil.parseObj(posterTemplate);
+        }catch (Exception e){
+            throw new BaseException(e.getMessage() +"---"+posterTemplate);
+        }
+        //JSONObject jsonObject = JSONUtil.parseObj(posterTemplate);
+        GoRequest goRequest = new GoRequest();
+        BeanUtil.copyProperties(jsonObject,goRequest);
+       // StringBuilder stringBuilder = getStringBuilder(goRequest);
+        if(Objects.nonNull(qsSetting)){
+            Optional<Item> first = goRequest.getItem().stream().filter(f -> "qrcode".equals(f.getT())).findFirst();
+            if (first.isPresent()) {
+                Item item = first.get();
+                Boolean isRandom = item.getIsRandom();
+                if (isRandom && Objects.nonNull(qsSetting.status()) &&  qsSetting.status()==1
+                        &&Objects.nonNull(qsSetting.serviceGroupType()) &&  qsSetting.serviceGroupType()==2 ) {
+                    String kefu = qsSetting.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("客服二维码");
+                            return goRequest;
+                        }
+                    }
+                }else if(Objects.nonNull(qsSetting.status()) &&  qsSetting.status()==0) {
+                    item.setV(spare);
+                    item.setName("H5二维码");
+                    return goRequest;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 废弃/废弃/废弃/废弃/废弃/废弃/ h5-通过code (第一个接口)
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link DataLists}>>
+     */
+//    @PostMapping("hfoInfo1")
+//    public Mono<RStatus<DataLists>> hfoInfo1(@RequestBody HfoRequest request){
+//        Mono<DataLists> map = Mono.just(new DataLists()).map(dataLists -> {
+//            template.selectOne(Query.query(Criteria.where("code").is(request.getCode())), PlanNew.class)
+//                    .subscribe(dataLists::setPlanNew);
+//            return dataLists;
+//        }).map(dataLists -> {
+//            template.selectOne(Query.query(Criteria.where("id").is(dataLists.getPlanNew().listAudioId())), Audio.class)
+//                    .subscribe(dataLists::setListAudio);
+//            return dataLists;
+//        }).map(dataLists -> {
+//            template.selectOne(Query.query(Criteria.where("id").is(dataLists.getPlanNew().retAudioId())), Audio.class)
+//                    .subscribe(dataLists::setRetAudio);
+//            return dataLists;
+//        }).map(dataLists -> {
+//            Integer integer = dataLists.getPlanNew().pageShow();//群数量
+//          //  Integer integer1 = dataLists.getPlanNew().pageLine();//单行数量
+//            template.select(Query.query(Criteria.where("type").is(1)), Image.class).limitRate(integer).collectList()
+//                    .subscribe(images -> {
+//                        template.select(Query.query(Criteria.where("type").is(4)),Material.class).limitRate(integer).collectList().subscribe(text->{
+//                            ArrayList<H5ImageAndText> h5ImageAndTexts = new ArrayList<>();
+//                            AtomicInteger adder = new AtomicInteger(0);
+//                            images.forEach(f1->{
+//                                H5ImageAndText h5ImageAndText = new H5ImageAndText();
+//                                h5ImageAndText.setImage(f1.image());
+//                                if(adder.get()>=text.size()){
+//                                    Material material = text.get(text.size() - 1);
+//                                    h5ImageAndText.setName(material.content());
+//                                }else {
+//                                    Material material = text.get(adder.get());
+//                                    h5ImageAndText.setName(material.content());
+//                                }
+//                                h5ImageAndTexts.add(h5ImageAndText);
+//                                adder.incrementAndGet();
+//                            });
+//                            dataLists.setImages(h5ImageAndTexts);
+//                        });
+//                    });
+//            return dataLists;
+//        }).map(dataLists -> {
+//            Integer top = dataLists.getPlanNew().topAdvBl();
+//            if (1 == top) {//广告类型1顶部2底部3返回4安卓,ios的返回
+//                Integer integer = dataLists.getPlanNew().topAdvNum();
+//                template.select(Query.query(Criteria.where("type").is(1)), Ad.class).limitRate(integer).collectList()
+//                        .subscribe(dataLists::setTopAd);
+//            }
+//            Integer bottom = dataLists.getPlanNew().bottomAdvBl();
+//            if (1 == bottom) {//广告类型1顶部2底部3返回4安卓,ios的返回
+//                Integer integer = dataLists.getPlanNew().topAdvNum();
+//                template.select(Query.query(Criteria.where("type").is(2)), Ad.class).limitRate(integer).collectList()
+//                        .subscribe(dataLists::setBottomAd);
+//            }
+//            return dataLists;
+//        }).map(dataLists -> {
+//            Integer integer = dataLists.getPlanNew().returnLoopBl();
+//            if (integer == 1) {
+//                template.selectOne(Query.query(Criteria.where("id").is(dataLists.getPlanNew().returnLoopId())), ReturnLoop.class)
+//                        .subscribe(dataLists::setReturnLoop);
+//            }
+//            return dataLists;
+//        });
+//        return RStatus.successList(map);
+//    }
+    /**
+     *废弃/废弃/废弃/废弃/废弃/废弃/  h5-通过code (第二个接口)
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link DataLists}>>
+     */
+//    @PostMapping("hftInfo1")
+//    public Mono<RStatus<DataLists0>> hftInfo1(@RequestBody HftRequest request){
+//        Mono<DataLists0> map = Mono.just(new DataLists0()).map(dataLists -> {
+//            template.selectOne(Query.query(Criteria.where("code").is(request.getCode())), PlanNew.class)
+//                    .subscribe(dataLists::setPlanNew);
+//            return dataLists;
+//        }).map(dataLists -> {
+//            template.selectOne(Query.query(Criteria.where("poster_template_id").is(dataLists.getPlanNew().posterTemplateId())), PosterTemplate.class)
+//                    .subscribe(dataLists::setPosterTemplate);
+//            return dataLists;
+//        }).map(dataLists -> {
+////            template.select(Query.query(Criteria.where("poster_template_id").is(dataLists.getPlanNew().posterTemplateId())), Poster.class).collectList()
+////                    .subscribe(dataLists::setPoster);
+//            return dataLists;
+//        }).map(dataLists -> {
+//            Long planNewId = dataLists.getPlanNew().planNewId();
+//            template.select(Query.query(Criteria.where("plan_new_id")
+//                    .is(planNewId)),PlanNewBackgroupPoster.class)
+//                    .collectList().subscribe(lt->{//qsOrFx,//1:分享背景组 2:清水背景组
+//                Map<Integer, List<PlanNewBackgroupPoster>> collect = lt.stream().collect(Collectors.groupingBy(PlanNewBackgroupPoster::qsOrFx));
+//                List<PlanNewBackgroupPoster> planNewBackgroupPosters = collect.get(1);
+//              //  dataLists.setFxSetting(planNewBackgroupPosters);
+//                List<PlanNewBackgroupPoster> planNewBackgroupPosters1 = collect.get(2);
+//               // dataLists.setQsSetting(planNewBackgroupPosters1);
+//            });
+//            return dataLists;
+//        });
+//        return RStatus.successList(map);
+//    }
+//
+
+    /**
+     * 废弃/废弃/废弃/废弃/废弃/废弃/ H5 接口(第一版废弃)
+     * @param request
+     * @return {@link Mono}<{@link RStatus}<{@link DataLists1}>>
+     */
+    @PostMapping("listH5")
+    public Mono<RStatus<DataLists1>> pageTempItem(@RequestBody PlanCodeRequest request){
+        Mono<DataLists1> map = Mono.just(new DataLists1()).map(dataLists -> {
+            template.selectOne(Query.query(Criteria.where("code").is(request.getCode())), PlanNew.class)
+                    .subscribe(dataLists::setPlanNew);
+            return dataLists;
+        }).map(dataLists -> {
+            template.selectOne(Query.query(Criteria.where("id").is(dataLists.getPlanNew().listAudioId())), Audio.class)
+                    .subscribe(dataLists::setListAudio);
+            return dataLists;
+        }).map(dataLists -> {
+            template.selectOne(Query.query(Criteria.where("id").is(dataLists.getPlanNew().retAudioId())), Audio.class)
+                    .subscribe(dataLists::setRetAudio);
+            return dataLists;
+        }).map(dataLists -> {
+            template.selectOne(Query.query(Criteria.where("id").is(dataLists.getPlanNew().backgroundGroupId())), BackgroupImage.class)
+                    .subscribe(dataLists::setBackgroupImage);
+            return dataLists;
+        }).map(dataLists -> {
+            template.select(Query.query(Criteria.where("group_id").is(dataLists.getPlanNew().backgroundGroupId())), BackgroupImageItem.class).collectList()
+                    .subscribe(dataLists::setBackgroupImageItemList);
+            return dataLists;
+        }).map(dataLists -> {
+            template.selectOne(Query.query(Criteria.where("poster_template_id").is(dataLists.getPlanNew().posterTemplateId())), PosterTemplate.class)
+                    .subscribe(dataLists::setPosterTemplate);
+            return dataLists;
+        }).map(dataLists -> {
+            template.select(Query.query(Criteria.where("poster_template_id").is(dataLists.getPlanNew().posterTemplateId())), Poster.class).collectList()
+                    .subscribe(dataLists::setPoster);
+            return dataLists;
+        }).map(dataLists -> {
+            template.selectOne(Query.query(Criteria.where("id").is(dataLists.getPlanNew().returnLoopId())), ReturnLoop.class)
+                    .subscribe(dataLists::setReturnLoop);
+            return dataLists;
+        });
+        return RStatus.successList(map);
+    }
+
+}

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

@@ -0,0 +1,8 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+
+import lombok.Data;
+
+@Data
+public class AudioRequest {
+    private String  name;
+}

+ 14 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/BackgroupRequest.java

@@ -0,0 +1,14 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Data
+public class BackgroupRequest {
+    private String  name;
+    /**
+     * 类型 1素材分类2清水分类
+     */
+    @NotNull
+    private Integer groupType;
+}

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

@@ -0,0 +1,11 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+
+import lombok.Data;
+
+@Data
+public class HfoRequest {
+    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/planNew/req/HftRequest.java

@@ -0,0 +1,12 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+
+import lombok.Data;
+
+@Data
+public class HftRequest {
+    private String code;
+    private String unique;
+    private String wx_user_id;
+    private Integer userVisits;
+    //listType是1的变成返回列表内容
+}

+ 19 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/KefuRequest.java

@@ -0,0 +1,19 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+
+import lombok.Data;
+
+@Data
+public class KefuRequest {
+    private String code;
+    private String unique;
+   // private String wxUserId;
+    private String wx_user_id;
+    /** 群数量 */
+    private Integer pageShow;
+    /** 分享背景组id */
+    private Long backgroundGroupId;
+    /** 返回音频id */
+    private Long retAudioId;
+    /** 百度统计code */
+    private String baiduDot;
+}

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

@@ -0,0 +1,29 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+
+import lombok.Data;
+
+/**
+ * H5域名查询请求体
+ *
+ * @author: wangcheng
+ * @date: 2024/7/10 15:13
+ */
+@Data
+public class OutDomainRequest {
+    private String code;
+    /** 计划类型 1.加群计划 2.听书计划 3.交友计划  */
+    private Integer typePlan;
+    /** 域名类型 1是入口域名,2是落地页域名,4是分享背景组域名,5是中转页域名 */
+    private Integer type;
+    /** 落地页域名 */
+    private String landingPageDomain;
+    /**
+     * 中转页域名
+     */
+    private String transferPageDomain;
+
+    /**
+     * 背景组域名
+     */
+    private String backgroupDomain;
+}

+ 9 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PlanCodeRequest.java

@@ -0,0 +1,9 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+
+import lombok.Data;
+
+@Data
+public class PlanCodeRequest {
+    private String code;
+    private String unique;
+}

+ 26 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PlanNewCommonMaterialReq.java

@@ -0,0 +1,26 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+
+import lombok.Data;
+
+/**
+ * H5通用计划素材请求体
+ *
+ * @author: wangcheng
+ * @date: 2024/7/10 17:59
+ */
+@Data
+public class PlanNewCommonMaterialReq {
+    private String code;
+    /** 群音频id */
+    private Long audioId;
+    /** 返回音频id */
+    private Long retAudioId;
+    /** 返回广告 */
+    private Long returnLoopId;
+    /** 分享背景组id */
+    private Long backgroundGroupId;
+    /**
+     * 外卖模版id
+     */
+    private Long takeawayId;
+}

+ 25 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PlanNewCommonShareReq.java

@@ -0,0 +1,25 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+
+import lombok.Data;
+
+/**
+ * H5通用计划分享请求体
+ *
+ * @author: wangcheng
+ * @date: 2024/7/11 09:46
+ */
+@Data
+public class PlanNewCommonShareReq {
+    private String code;
+    private String unique;
+    private String wx_user_id;
+    private Integer userVisits;
+    /** 1三方链接 2计划链接 */
+    private Integer redirectType;
+    /** 计划链接id */
+    private String redirectPlanId;
+    /** 入群链接 */
+    private String link;
+    /** 清水分类id */
+    private Long groupIdQs;
+}

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

@@ -0,0 +1,163 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class PlanReq {
+
+    private String planNewId;
+    /**
+     * 计划名
+     */
+    private String name; //计划名
+//    private String createUser;
+//    private String createId;
+    /**
+     * // 1.加群计划 2.听书计划 3.交友计划
+     */
+    private  Integer type;
+    /**
+     *
+     */
+    private  String code;
+    /**
+     *分类id
+     */
+    private Long  groupId; //分类id
+    /**
+     *海报id
+     */
+    @NotNull
+    private  Long posterTemplateId;//海报id
+    /**
+     *群数量
+     */
+    private  Integer pageShow;//群数量
+    /**
+     *单行数量
+     */
+    private Integer pageLine;//单行数量
+    /**
+     *清水分类/展示次数
+     */
+    private Integer count;//清水分类/展示次数
+    /**
+     *列表音频id
+     */
+    private Long listAudioId;//	列表音频id
+    /**
+     *返回音频id
+     */
+    private  Long retAudioId;//返回音频id
+    /**
+     *入群链接
+     */
+    private String link;//入群链接
+    /**
+     *加群确认页开关
+     */
+    private Integer  isAddQun;//加群确认页开关
+    /**
+     *背景组id
+     */
+    private Long backgroundGroupId;//背景组id
+    /**
+     *首页模版id
+     */
+    private  Long homePageId;//首页模版id
+    /**
+     *顶部广告 -1 false  其他true
+     */
+    private Integer topAdvNum;//顶部广告 -1 false  其他true
+    /**
+     *底部广告 -1 false  其他true
+     */
+    private Integer bottomAdvNum;//	底部广告 -1 false  其他true
+    /**
+     *返回广告 -1 false  其他true
+     */
+    private Long returnLoopId;//	返回广告 -1 false  其他true
+    /**
+     * 清水背景组id
+     */
+    private Long backgroundGroupQsId;
+    /**
+     *顶部广告 false  true
+     */
+    private Integer topAdvBl;
+    /**
+     *底部广告 false  true
+     */
+    private Integer bottomAdvBl;
+    /**
+     *返回广告  false  true
+     */
+    private Integer returnLoopBl;
+
+    private Long  groupIdQs;
+
+    private String  baiduDot;
+
+    /**
+     * 入群方式 // 1三方链接 2计划链接
+     */
+    @NotNull
+    private  Integer redirectType;
+    /**
+     * 选择计划
+     */
+    private  String redirectPlanId;
+
+
+    /**
+     * 分享背景组id
+     */
+    private Long backgroundGroupIdNewAdd;
+
+    /**
+     * 分享背景组-配置
+     */
+    @NotEmpty
+    private List<ServiceGroupSettingItemRequest> backgroupFxSetting;
+    /**
+     * 清水背景组-配置
+     */
+    private List<ServiceGroupSettingItemRequest> backgroupQsSetting;
+
+    /**
+     * 按钮名称
+     */
+   private String listButton;
+
+    /**
+     * 入口域名
+     */
+    private String importDomain; //入口域名
+    /**
+     * 落地页域名
+     */
+    private String landingPageDomain;//落地页域名
+    /**
+     * 中转页域名
+     */
+    private String transferPageDomain;//中转页域名
+    /**
+     * 中转页开关 1:true 0:F
+     */
+    private Integer transferPageBl; //中转页开关 1:true 0:F
+    /**
+     * 背景组域名
+     */
+    private String backgroupDomain;//背景组域名
+
+    /** 配置json */
+    private String configJson;
+
+    /**
+     * 群列表展示
+     */
+    private Integer groupListDisplay;
+}

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

@@ -0,0 +1,32 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+
+import lombok.Data;
+
+/**
+ * @author moka
+ */
+@Data
+public class PlanReqPage {
+
+
+    private Integer page;
+    private Integer size;
+
+    /**
+     * 计划名
+     */
+    private String name;
+    private String createUser;
+    /**
+     * 1加群裂变2听书计划
+     */
+    private Integer type;
+    private String code;
+    /**
+     * 海报id
+     */
+    private Long posterTemplateId;
+    /** 分类 */
+    private Long groupId;
+
+}

+ 15 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PosterPage.java

@@ -0,0 +1,15 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+import lombok.Data;
+
+@Data
+public class PosterPage {
+
+
+    private Integer page;
+    private Integer size;
+
+
+    private String posterTemplateId; //模版id
+
+
+}

+ 9 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PosterReq.java

@@ -0,0 +1,9 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+
+import lombok.Data;
+
+@Data
+public class PosterReq {
+   private Long posterTemplateId;
+   private String posterTemplate;
+}

+ 19 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PosterRequest.java

@@ -0,0 +1,19 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Data
+public class PosterRequest {
+
+   private Long posterId;
+    /**
+     * 模版Id
+     */
+   private Long posterTemplateId;
+    /**
+     * 内容
+     */
+    @NotNull
+   private String posterTemplate;
+}

+ 15 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PosterTemPage.java

@@ -0,0 +1,15 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+import lombok.Data;
+
+@Data
+public class PosterTemPage {
+
+
+    private Integer page;
+    private Integer size;
+
+
+    private String name; //模版名
+
+
+}

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

@@ -0,0 +1,11 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+import lombok.Data;
+
+@Data
+public class PosterTemSelect {
+
+
+    private String name; //模版名
+
+
+}

+ 20 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PosterTemSelectSelf.java

@@ -0,0 +1,20 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Data
+public class PosterTemSelectSelf {
+
+
+    /**
+     * 模版名
+     */
+    private String name;
+    /**
+     * 用户Id
+     */
+    @NotNull
+    private String userId;
+
+
+}

+ 13 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/PosterTemplateRequset.java

@@ -0,0 +1,13 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+
+import lombok.Data;
+
+@Data
+public class PosterTemplateRequset {
+
+    private Long posterTemplateId;
+    /**
+     * 海报模板名称
+     */
+    private String    posterTemplateName;//
+}

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

@@ -0,0 +1,8 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+
+import lombok.Data;
+
+@Data
+public class ReturnLoopRequest {
+    private String  name;
+}

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

@@ -0,0 +1,8 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+
+import lombok.Data;
+
+@Data
+public class ServiceGroupRequest {
+    private Integer  status;
+}

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

@@ -0,0 +1,22 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+import lombok.Data;
+
+@Data
+public class ServiceGroupSettingItemRequest {
+    /**
+     *  保存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:上传图片
+}
+
+  

+ 30 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/req/ServiceGroupSettingRequest.java

@@ -0,0 +1,30 @@
+package com.webflux.launchadmin.mysql.controller.planNew.req;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class ServiceGroupSettingRequest {
+
+    List<ServiceGroupSettingItemRequest> lists;
+    /**
+     *  保存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  Integer serviceGroupId;//客服组 ,分割
+    private  Integer serviceGroupType ;//1:客服组 2:上传图片
+    /**
+     * 计划id
+     */
+    private Long    planNewId;
+}
+
+  

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

@@ -0,0 +1,23 @@
+package com.webflux.launchadmin.mysql.controller.planNew.res;
+
+import com.webflux.launchadmin.mysql.entity.planNew.*;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class BackgroupImageRes {
+    private PlanNew planNew;
+
+    /**
+     *背景主任务
+     */
+    private BackgroupImage backgroupImage;
+
+    /**
+     * 背景子任务
+     */
+    private List<BackgroupImageItem> backgroupImageItemList;
+
+
+}

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

@@ -0,0 +1,9 @@
+package com.webflux.launchadmin.mysql.controller.planNew.res;
+
+import java.util.List;
+
+public record DataList<T,E,R>(
+        List<T> audio,
+        List<E> backgroupImage,
+        List<R> backgroupImageItem) {
+}

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

@@ -0,0 +1,64 @@
+package com.webflux.launchadmin.mysql.controller.planNew.res;
+
+import com.webflux.launchadmin.mysql.entity.planNew.*;
+import lombok.Data;
+
+import java.util.List;
+@Data
+public class DataLists {
+    /**
+     * 计划
+     */
+    private PlanNew planNew;
+    /**
+     * 列表音频
+     */
+    private Audio listAudio;
+
+    /**
+     * 返回音频
+     */
+    private Audio retAudio;
+
+    /**
+     * 群封面头像数组
+     */
+    List<H5ImageAndText> images;
+
+    /**
+     * 顶部广告
+     */
+    private List<Ad>  topAd;
+
+    /**
+     * 底部广告
+     */
+    private List<Ad> bottomAd;
+
+    /**
+     * 返回广告
+     */
+    private ReturnLoop returnLoop;
+
+    /**
+     * 1表示清水素材超过展示次数
+     */
+    private Integer isRet;
+
+    /**
+     * 中转页域名
+     */
+    private String transferPageDomain;//中转页域名
+    /**
+     * 中转页开关 1:true 0:F
+     */
+    private Integer transferPageBl; //中转页开关 1:true 0:F
+    /**
+     * 背景组域名
+     */
+    private String backgroupDomain;//背景组域名
+
+    private String  listButton;
+
+
+}

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

@@ -0,0 +1,107 @@
+package com.webflux.launchadmin.mysql.controller.planNew.res;
+
+import com.webflux.launchadmin.mysql.entity.planNew.*;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class DataLists0 {
+    /**
+     * 计划
+     */
+    private PlanNew planNew;
+
+
+    /**
+     * 海报模版
+     */
+    private PosterTemplate posterTemplate;
+
+    /**
+     * 海报组
+     */
+    private Poster poster;
+
+    /**
+     * 分享-配置
+     */
+    private PlanNewBackgroupPoster fxSetting;
+    /**
+     * 清水-配置
+     */
+    private PlanNewBackgroupPoster qsSetting;
+    /**
+     * 分享-生成图片
+     */
+    private String fxGenerateImagesUrl;
+    /**
+     * 清水-生成图片
+     */
+    private String qsGenerateImagesUrl;
+
+    /**
+     * 音频
+     */
+    private Audio audio;
+    /**
+     *
+     */
+    private String link;
+    private Integer redirectType;
+
+    private  String limitTime;
+
+    private String limitTimeRemark;
+
+    private String spare;
+    /**
+     * 群头像
+     */
+    private String groupHeadUrl;
+    /**
+     * 群名称
+     */
+    private String groupTitle;
+
+    private Integer groupListDisplay;
+
+//
+//    /**
+//     * 列表音频
+//     */
+//    private Audio listAudio;
+//
+//    /**
+//     * 返回音频
+//     */
+//    private Audio retAudio;
+//
+//    /**
+//     *背景主任务
+//     */
+//    private BackgroupImage backgroupImage;
+//
+//    /**
+//     * 背景子任务
+//     */
+//    private List<BackgroupImageItem> backgroupImageItemList;
+//
+//    /**
+//     * 海报模版
+//     */
+//    private PosterTemplate posterTemplate;
+//
+//    /**
+//     * 海报组
+//     */
+//    private List<Poster> poster;
+//
+//    /**
+//     * 返回广告
+//     */
+//    private ReturnLoop returnLoop;
+
+
+
+}

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

@@ -0,0 +1,48 @@
+package com.webflux.launchadmin.mysql.controller.planNew.res;
+
+import com.webflux.launchadmin.mysql.entity.planNew.*;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class DataLists1 {
+    private PlanNew planNew;
+    /**
+     * 列表音频
+     */
+    private Audio listAudio;
+
+    /**
+     * 返回音频
+     */
+    private Audio retAudio;
+
+    /**
+     *背景主任务
+     */
+    private BackgroupImage backgroupImage;
+
+    /**
+     * 背景子任务
+     */
+    private List<BackgroupImageItem> backgroupImageItemList;
+
+    /**
+     * 海报模版
+     */
+    private PosterTemplate posterTemplate;
+
+    /**
+     * 海报组
+     */
+    private List<Poster> poster;
+
+    /**
+     * 返回广告
+     */
+    private ReturnLoop returnLoop;
+
+
+
+}

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

@@ -0,0 +1,59 @@
+package com.webflux.launchadmin.mysql.controller.planNew.res;
+
+import com.webflux.launchadmin.mysql.entity.planNew.*;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class DataListsKefu {
+    /**
+     * 计划
+     */
+    private PlanNew planNew;
+
+    private PlanNewCommon planNewCommon;
+//    /**
+//     * 列表音频
+//     */
+//    private Audio listAudio;
+
+    /**
+     * 返回音频
+     */
+    private Audio retAudio;
+
+    /**
+     * 群封面头像数组
+     */
+    List<H5ImageAndText> images;
+
+
+    private String baiduDot;
+
+
+    private List<String>  shareQrurl;
+
+//    /**
+//     * 顶部广告
+//     */
+//    private List<Ad>  topAd;
+//
+//    /**
+//     * 底部广告
+//     */
+//    private List<Ad> bottomAd;
+//
+//    /**
+//     * 返回广告
+//     */
+//    private ReturnLoop returnLoop;
+//
+//    /**
+//     * 1表示清水素材超过展示次数
+//     */
+//    private Integer isRet;
+
+
+
+}

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

@@ -0,0 +1,25 @@
+package com.webflux.launchadmin.mysql.controller.planNew.res;
+
+import lombok.Data;
+
+/**
+ * @author moka
+ */
+@Data
+public class DomainSelectRes {
+    private String domain;
+    private String path;
+    private String unique;
+    /**
+     * 中转页域名
+     */
+    private String transferPageDomain;
+    /**
+     * 中转页开关 1:true 0:F
+     */
+    private Integer transferPageBl;
+    /**
+     * 背景组域名
+     */
+    private String backgroupDomain;
+}

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

@@ -0,0 +1,17 @@
+package com.webflux.launchadmin.mysql.controller.planNew.res;
+
+import lombok.Data;
+
+/**
+ * 群成员返回体
+ *
+ * @author: wangcheng
+ * @date: 2024/7/10 15:55
+ */
+@Data
+public class GroupUserRes {
+    /** 头像 */
+    String userHead;
+    /** 昵称 */
+    String userNickname;
+}

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

@@ -0,0 +1,21 @@
+package com.webflux.launchadmin.mysql.controller.planNew.res;
+
+import lombok.Data;
+
+@Data
+public class H5ImageAndText {
+    /**
+     * 群封面头像
+     */
+  private  String image;
+    /**
+     * 群封面名称
+     */
+  private String name;
+    /**
+     * 域名
+     */
+  private String  domain;
+
+  private String  remark;
+}

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

@@ -0,0 +1,73 @@
+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  String redirectPlanId;
+    private  String listButton;
+
+    /**
+     * 入口域名
+     */
+    private Integer importDomain; //入口域名
+    /**
+     * 落地页域名
+     */
+    private Integer landingPageDomain;//落地页域名
+    /**
+     * 中转页域名
+     */
+    private Integer transferPageDomain;//中转页域名
+    /**
+     * 中转页开关 1:true 0:F
+     */
+    private Integer transferPageBl; //中转页开关 1:true 0:F
+    /**
+     * 背景组域名
+     */
+    private Integer backgroupDomain;//背景组域名
+
+
+    private Integer groupListDisplay;
+}

+ 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;
+}

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

@@ -0,0 +1,41 @@
+package com.webflux.launchadmin.mysql.controller.planNew.res;
+
+import com.webflux.launchadmin.mysql.controller.takeawayController.res.TakeawayH5Data;
+import com.webflux.launchadmin.mysql.entity.planNew.Audio;
+import com.webflux.launchadmin.mysql.entity.planNew.ReturnLoop;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * H5通用计划素材返回体
+ *
+ * @author: wangcheng
+ * @date: 2024/7/10 18:07
+ */
+@Data
+public class PlanNewCommonMaterialRes {
+    /**
+     * 群音频
+     */
+    private Audio groupAudio;
+
+    /**
+     * 返回音频
+     */
+    private Audio retAudio;
+
+    /**
+     * 返回广告
+     */
+    private ReturnLoop returnLoop;
+
+    /**
+     * 分享背景组
+     */
+    private List<String> shareUrls;
+    /**
+     *
+     */
+    private TakeawayH5Data takeawayH5Data;
+}

Некоторые файлы не были показаны из-за большого количества измененных файлов