Kaynağa Gözat

Merge branch 'volta' into pro

# Conflicts:
#	launch-admin/src/main/java/com/webflux/launchadmin/config/LoginWebFiter.java
#	launch-admin/src/main/java/com/webflux/launchadmin/mysql/controller/planNew/PlanNewCommonOutController.java
volta 2 yıl önce
ebeveyn
işleme
4759c2039d

+ 1 - 1
Dockerfile

@@ -2,7 +2,7 @@ FROM jdk21-alpine:3.18
 
 ARG env
 
-#ENV ENVIRMENT=${env:+"dev"}
+ENV ENVIRMENT=${env:+"dev"}
 ENV ENVIRMENT=${ENVIRMENT:-"prod"}
 
 COPY ./launch-admin/target/*.jar  /app/lbservice.jar

+ 1 - 2
launch-admin/src/main/java/com/webflux/launchadmin/LaunchAdminApplication.java

@@ -1,7 +1,7 @@
 package com.webflux.launchadmin;
 
 
-
+import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.scheduling.annotation.EnableScheduling;
@@ -9,7 +9,6 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
 
 @EnableTransactionManagement
 @SpringBootApplication(scanBasePackages = "com.*")
-
 @EnableScheduling
 public class LaunchAdminApplication {
 

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

@@ -1,33 +0,0 @@
-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);
-    }
-}

+ 19 - 12
launch-admin/src/main/java/com/webflux/launchadmin/config/LoginWebFiter.java

@@ -18,14 +18,13 @@ 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.*;
 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.cors.reactive.CorsUtils;
 import org.springframework.web.server.ServerWebExchange;
 import org.springframework.web.server.WebFilter;
 import org.springframework.web.server.WebFilterChain;
@@ -51,7 +50,24 @@ public class LoginWebFiter implements WebFilter {
     @Override
     public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
         ServerHttpRequest request = exchange.getRequest();
+        ServerHttpResponse response = exchange.getResponse();
         RequestPath path = request.getPath();
+        //.跨域
+        if (CorsUtils.isCorsRequest(request)) {
+            HttpHeaders headers = response.getHeaders();
+            //解决跨域的问题
+            headers.add("Access-Control-Allow-Origin", "*");
+            headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
+            headers.add("Access-Control-Allow-Headers", "*");
+            headers.add("Access-Control-Max-Age", "3600");
+            headers.add("Access-Control-Allow-Credentials", "true");
+        }
+        //预检请求
+        if (request.getMethod().equals(HttpMethod.OPTIONS.name())) {
+            response.setStatusCode(HttpStatus.OK);
+            return response.setComplete();
+        }
+
         String string = path.toString();
         String[] split = xxlSsoExcludedPaths.split(",");
         String[] split1 = xxlSsoExcludedstart.split(",");
@@ -72,7 +88,6 @@ public class LoginWebFiter implements WebFilter {
                log.error("LoginWebFiter getUserInfo E:"+ e.getMessage());
            }
         }
-        System.out.println("...abcd");
         Mono<Void> filter = chain.filter(exchange); //放行
         //流一旦经过某个操作就会变成新流
         Mono<Void> voidMono = filter.doOnError(err -> {
@@ -111,7 +126,6 @@ public class LoginWebFiter implements WebFilter {
 
     public Boolean getUser(String cookie) throws IOException {
         if (Objects.isNull(cookie)) {
-            log.warn("111111111, no cookie");
             return false;
         }
         if(UserContext.cMap.containsKey(cookie)){
@@ -129,14 +143,10 @@ public class LoginWebFiter implements WebFilter {
             HttpEntity entity = response.getEntity();
             String result = EntityUtils.toString(entity);
             EntityUtils.consume(entity);
-            log.warn("3");
             if (Objects.nonNull(result)) {
-                log.warn("4");
                 JSONObject jsonObject = JSONUtil.parseObj(result);
                 if (jsonObject.containsKey("code") && jsonObject.get("code", Integer.class) == 200) {
-                    log.warn("5");
                     if(jsonObject.containsKey("data")){
-                        log.warn("7");
                         XxlSsoUser data = jsonObject.get("data", XxlSsoUser.class);
                         BaseContextHandler.setUserId(data.getUserid());
                         BaseContextHandler.setUserName(data.getUsername());
@@ -145,19 +155,16 @@ public class LoginWebFiter implements WebFilter {
                         return true;
                     }
                 }else if(jsonObject.containsKey("code") && jsonObject.get("code", Integer.class) == 501){
-                    log.warn("7.1");
                     return false;
                 }else {
                     return true;
                 }
             }
-            log.warn("8");
         } catch (Exception e) {
             return true;
         } finally {
             response.close();
         }
-        log.warn("2222222222222");
         return true;
 
     }

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

@@ -1,25 +0,0 @@
-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");
-            }
-        };
-    }
-}

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

@@ -2,6 +2,7 @@ package com.webflux.launchadmin.dispatcher;
 
 import com.webflux.launchadmin.context.UserContext;
 import lombok.extern.slf4j.Slf4j;
+import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
@@ -18,6 +19,7 @@ public class MailTask {
 
     //清空用户Map数据 每天凌晨执行
 	@Scheduled(cron="1 1 0 * * ?")
+	@SchedulerLock(name = "launch:MailTask:clearUserContextMap", lockAtLeastFor = "PT5S", lockAtMostFor = "PT15M")
 	public void clearUserContextMap(){
 		log.info("清空用户Map数据》》》》》》》》》》》》》》》》》》》》》》开始");
 		UserContext.cMap.clear();

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

@@ -7,12 +7,10 @@ import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONArray;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSON;
 import com.plumelog.core.util.LogExceptionStackTrace;
 import com.webflux.launchadmin.global.BaseException;
-import com.webflux.launchadmin.mysql.controller.planNew.req.KefuRequest;
-import com.webflux.launchadmin.mysql.controller.planNew.req.OutDomainRequest;
-import com.webflux.launchadmin.mysql.controller.planNew.req.PlanNewCommonMaterialReq;
-import com.webflux.launchadmin.mysql.controller.planNew.req.PlanNewCommonShareReq;
+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;
@@ -26,11 +24,15 @@ 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 net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
+import org.apache.commons.lang3.exception.ExceptionUtils;
 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.RedisTemplate;
+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.scheduling.annotation.Scheduled;
@@ -70,6 +72,7 @@ public class PlanNewCommonOutController {
     private static final ConcurrentHashMap<String, Integer> MAP = new ConcurrentHashMap<>();
 
     @Scheduled(cron = "1 1 4 * * ?")
+    @SchedulerLock(name = "launch:PlanNewCommonOutController:clearUserContextHashMap", lockAtLeastFor = "PT5S", lockAtMostFor = "PT15M")
     public void clearUserContextHashMap() {
         log.info("清空计划-H5用户Map数据》》》》》》》》》》》》》》》》》》》》》》开始");
         MAP.clear();
@@ -85,8 +88,8 @@ public class PlanNewCommonOutController {
     @GetMapping("getPlanNewCommonH5")
     public Mono<RStatus<byte[]>> getPlanNewCommonH5(@RequestParam("code") String code) {
         Mono<PlanNewCommon> planNewCommonMono = template.selectOne(Query.query(Criteria.where("code").is(code)), PlanNewCommon.class)
-                .switchIfEmpty(Mono.error(new BaseException("计划code异常")))
-                .onErrorResume(throwable -> Mono.error(new BaseException("计划code异常")));
+                .switchIfEmpty(Mono.error(new BaseException("计划code异常" + ExceptionUtils.getStackTrace(new Exception()))))
+                .onErrorResume(throwable -> Mono.error(new Exception(LogExceptionStackTrace.erroStackTrace(throwable).toString())));
         Mono<PlanNewCommonRes> resMono = planNewCommonMono.flatMap(f -> {
             // 群成员
             Mono<List<GroupUserRes>> groupUserResMono = Mono.just(new ArrayList<>());
@@ -94,16 +97,16 @@ public class PlanNewCommonOutController {
             Mono<List<Image>> imageMono = template.select(Query.query(Criteria.where("type").is(1)
                             .and("group_type_id").is(f.groupId())
                             .and("deleted_at").isNull()), Image.class)
-                    .onErrorResume(throwable -> Mono.error(new BaseException("获取群封面异常"))).collectList();
+                    .onErrorResume(throwable -> Mono.error(new Exception(LogExceptionStackTrace.erroStackTrace(throwable).toString()))).collectList();
             // 群名称
             Mono<List<Material>> textMono = template.select(Query.query(Criteria.where("type").is(4)
                             .and("deleted_at").isNull()
                             .and("group_type_id").is(f.groupId())), Material.class)
-                    .onErrorResume(throwable -> Mono.error(new BaseException("获取群名称异常"))).collectList();
+                    .onErrorResume(throwable -> Mono.error(new Exception(LogExceptionStackTrace.erroStackTrace(throwable).toString()))).collectList();
             if (3 == f.type()) {
                 // 交友裂变, 需要群成员
                 Mono<List<GroupUsers>> groupUsersMono = template.select(Query.query(Criteria.where("group_users_type").is(f.groupId())).limit(14), GroupUsers.class)
-                        .onErrorResume(throwable -> Mono.error(new BaseException("获取群成员异常"))).collectList();
+                        .onErrorResume(throwable -> Mono.error(new Exception(LogExceptionStackTrace.erroStackTrace(throwable).toString()))).collectList();
                 groupUserResMono = groupUsersMono.flatMap(groupUsers -> {
                     List<GroupUserRes> groupUserResList = groupUsers.stream().map(groupUsers1 -> {
                         GroupUserRes groupUserRes = new GroupUserRes();
@@ -175,7 +178,7 @@ public class PlanNewCommonOutController {
     public Mono<RStatus<byte[]>> kefuList(@RequestBody KefuRequest request) {
         Mono<PlanNewCommon> code = template.selectOne(Query.query(Criteria.where("code").is(request.getCode())), PlanNewCommon.class)
                 .switchIfEmpty(Mono.error(new BaseException("code查询返回结构为空")))
-                .onErrorResume(throwable -> Mono.error(new BaseException("code查询返回结构为空")));
+                .onErrorResume(throwable -> Mono.error(new Exception(LogExceptionStackTrace.erroStackTrace(throwable).toString())));
         Mono<DataListsKefu> dataListsKefuMono = code.flatMap(planNew -> {
             Mono<List<Image>> image = template.select(Query.query(Criteria.where("type").is(5)
                             .and("deleted_at").isNull()
@@ -183,13 +186,13 @@ public class PlanNewCommonOutController {
                     .collectList()
                     .switchIfEmpty(Mono.error(new BaseException(StrUtil.format("通过计划groupId:{}查询Image返回结构为空", planNew.groupId()))))
                     .onErrorResume(throwable ->
-                            Mono.error(new BaseException(StrUtil.format("通过计划groupId:{}查询Image返回结果error:{}", planNew.groupId(), throwable.getMessage()))));
+                            Mono.error(new Exception(StrUtil.format("通过计划groupId:{}查询Image返回结果error:{}", planNew.groupId(), LogExceptionStackTrace.erroStackTrace(throwable).toString()))));
             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 BaseException(StrUtil.format("通过计划groupId:{}查询Material返回结果error:{}", planNew.groupId(), throwable.getMessage()))))
+                            Mono.error(new Exception(StrUtil.format("通过计划groupId:{}查询Material返回结果error:{}", planNew.groupId(), LogExceptionStackTrace.erroStackTrace(throwable).toString()))))
                     .collectList();
             Mono<List<H5ImageAndText>> arrayListMono = Mono.zip(Mono.just(planNew), image, text).flatMap(f -> {
                 // H5ImageAndText
@@ -198,7 +201,7 @@ public class PlanNewCommonOutController {
                 List<Image> t3 = f.getT2();
                 List<Material> t4 = f.getT3();
                 if (t3.size() < integer || t4.size() < integer) {
-                    return Mono.error(new BaseException("图片或文字素材小于计划设置数"));
+                    throw new BaseException("图片或文字素材小于计划设置数");
                 }
                 ArrayList<Long> listImg = new ArrayList<>();
                 ArrayList<Long> listTxt = new ArrayList<>();
@@ -284,7 +287,7 @@ public class PlanNewCommonOutController {
         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 BaseException("计划code异常")));
+                .onErrorResume(throwable -> Mono.error(new Exception(LogExceptionStackTrace.erroStackTrace(throwable).toString())));
         Mono<DomainSelectRes> domainSelectResMono1 = code1.flatMap(f -> {
             Mono<String> stringMono;
             if (f.transferPageBl() == 1 && Objects.nonNull(f.transferPageDomain())) {
@@ -294,7 +297,7 @@ public class PlanNewCommonOutController {
                                 .and("type").is(5)
                                 .and("deleted_at").isNull()), DomainSelect.class)
                         .switchIfEmpty(Mono.error(new BaseException("transferPageDomain 域名查詢為空 group_type_id:::" + f.transferPageDomain())))
-                        .onErrorResume(throwable -> Mono.error(new BaseException("transferPageDomain 域名查詢為空 group_type_id:::" + f.transferPageDomain()))).collectList().flatMap(fff -> {
+                        .onErrorResume(throwable -> Mono.error(new Exception(LogExceptionStackTrace.erroStackTrace(throwable).toString()))).collectList().flatMap(fff -> {
                             if (!fff.isEmpty()) {
                                 DomainSelect domainSelect = fff.get(RandomUtil.randomInt(0, fff.size()));
                                 String string = RandomUtil.randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 6);
@@ -302,7 +305,7 @@ public class PlanNewCommonOutController {
                                 return Mono.just(string + "." + domain1);
 
                             } else {
-                                return Mono.error(new BaseException("transferPageDomain 中轉域名查詢為空 group_type_id:::" + f.transferPageDomain()));
+                                throw new BaseException("transferPageDomain 中轉域名查詢為空 group_type_id:::" + f.transferPageDomain());
                             }
                         });
             } else {
@@ -316,14 +319,14 @@ public class PlanNewCommonOutController {
                                 .and("type").is(4)
                                 .and("deleted_at").isNull()), DomainSelect.class)
                         .switchIfEmpty(Mono.error(new BaseException("backgroupDomain 域名查询为空 group_type_id" + f.backgroupDomain())))
-                        .onErrorResume(throwable -> Mono.error(new BaseException("backgroupDomain 域名查询为空 group_type_id" + f.backgroupDomain()))).collectList().flatMap(fff -> {
+                        .onErrorResume(throwable -> Mono.error(new Exception(LogExceptionStackTrace.erroStackTrace(throwable).toString()))).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 {
-                                return Mono.error(new BaseException("backgroupDomain 背景域名查詢為空 group_type_id" + f.backgroupDomain()));
+                                throw new BaseException("backgroupDomain 背景域名查詢為空 group_type_id" + f.backgroupDomain());
                             }
                         });
             } else {
@@ -335,7 +338,7 @@ public class PlanNewCommonOutController {
                             .and("type").is(request.getType())
                             .and("deleted_at").isNull()), DomainSelect.class)
                     .switchIfEmpty(Mono.error(new BaseException("查询domain 返回结果为空")))
-                    .onErrorResume(throwable -> Mono.error(new BaseException("查询domain 返回结果为空"))).collectList().flatMap(fm -> {
+                    .onErrorResume(throwable -> Mono.error(new Exception(LogExceptionStackTrace.erroStackTrace(throwable).toString()))).collectList().flatMap(fm -> {
                         //  DomainSelectRes domainSelectRes = new DomainSelectRes();
                         int i = RandomUtil.randomInt(0, fm.size());
                         String domain = fm.get(i).domain();
@@ -362,14 +365,14 @@ public class PlanNewCommonOutController {
     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 BaseException("计划code异常 返回结果为空")));
+                .onErrorResume(throwable -> Mono.error(new Exception(LogExceptionStackTrace.erroStackTrace(throwable).toString())));
         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 BaseException("查询domain 返回结果为空"))).collectList()
+                .onErrorResume(throwable -> Mono.error(new Exception(LogExceptionStackTrace.erroStackTrace(throwable).toString()))).collectList()
                 .flatMap(fm -> {
                     DomainSelectRes domainSelectRes = new DomainSelectRes();
                     int i = RandomUtil.randomInt(0, fm.size());
@@ -397,7 +400,7 @@ public class PlanNewCommonOutController {
                             .and("deleted_at").isNull()
                             .and("type").is(request.getType())), DomainSelect.class)
                     .switchIfEmpty(Mono.error(new BaseException("查询domain 返回结果为空")))
-                    .onErrorResume(throwable -> Mono.error(new BaseException("查询domain 返回结果为空")))
+                    .onErrorResume(throwable -> Mono.error(new Exception(LogExceptionStackTrace.erroStackTrace(throwable).toString())))
                     .collectList().flatMap(fm -> {
                         int i = RandomUtil.randomInt(0, fm.size());
                         String domain = fm.get(i).domain();
@@ -413,14 +416,14 @@ public class PlanNewCommonOutController {
                     .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 BaseException(throwable.getMessage()))).collectList().flatMap(fff -> {
+                    .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 {
-                            return Mono.error(new BaseException("transferPageDomain 中轉域名查詢為空 group_type_id:::" +  request.getTransferPageDomain()));
+                            throw new BaseException("transferPageDomain 中轉域名查詢為空 group_type_id:::" +  request.getTransferPageDomain());
                         }
                     });
         } else {
@@ -434,14 +437,14 @@ public class PlanNewCommonOutController {
                     .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 BaseException(throwable.getMessage()))).collectList().flatMap(fff -> {
+                    .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 {
-                            return Mono.error(new BaseException("backgroupDomain 背景域名查詢為空 group_type_id" + request.getBackgroupDomain()));
+                            throw new BaseException("backgroupDomain 背景域名查詢為空 group_type_id" + request.getBackgroupDomain());
                         }
                     });
         } else {
@@ -469,7 +472,7 @@ public class PlanNewCommonOutController {
                     .and("deleted_at").isNull()
                     .and("type").is(request.getType())), DomainSelect.class)
                     .switchIfEmpty(Mono.error(new BaseException("查询domain 返回结果为空")))
-                    .onErrorResume(throwable -> Mono.error(new BaseException(throwable.getMessage())))
+                    .onErrorResume(throwable -> Mono.error(new Exception(throwable.getMessage())))
                     .collectList().flatMap(fm -> {
                         int i = RandomUtil.randomInt(0, fm.size());
                         String domain = fm.get(i).domain();
@@ -497,7 +500,7 @@ public class PlanNewCommonOutController {
     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 BaseException("计划code异常 返回结果为空")));
+                .onErrorResume(throwable -> Mono.error(new Exception(LogExceptionStackTrace.erroStackTrace(throwable).toString())));
         Mono<PlanNewCommonMaterialRes> materialResMono = planNewCommonMono.flatMap(plan -> {
             // 群音频
             Mono<Audio> groupAudio = this.getAudio(request.getAudioId());
@@ -511,7 +514,7 @@ public class PlanNewCommonOutController {
                 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 BaseException("查询返回广告异常:::" + throwable.getMessage())));
+                        .onErrorResume(throwable -> Mono.error(new Exception(LogExceptionStackTrace.erroStackTrace(throwable).toString())));
             }
             // 分享背景组
             Mono<List<BackgroupImageItem>> backgroupImageItemMono;
@@ -521,17 +524,17 @@ public class PlanNewCommonOutController {
                 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 BaseException("查询分享背景组异常:::" + throwable.getMessage())));
+                        .onErrorResume(throwable -> Mono.error(new Exception(LogExceptionStackTrace.erroStackTrace(throwable).toString())));
             }
-            Mono<TakeawayH5Data> takeaway;
+            Mono<TakeawayH5Data> takeaway ;
             if (Objects.nonNull(request.getTakeawayId()) && request.getTakeawayId() > 0) {
                 takeaway = takeawayServicesInterface.getTakeaway(request.getTakeawayId())
                         .switchIfEmpty(Mono.just(new TakeawayH5Data()))
-                        .onErrorResume(e -> Mono.error(new BaseException("查询外卖模版数据异常:::" + e.getMessage())));
-            } else {
-                takeaway = Mono.just(new TakeawayH5Data());
+                        .onErrorResume(e->Mono.error(new BaseException("查询外卖模版数据异常:::"+LogExceptionStackTrace.erroStackTrace(e).toString())));
+            }else {
+                takeaway=Mono.just(new TakeawayH5Data());
             }
-            return Mono.zip(groupAudio, retAudio, returnLoop, backgroupImageItemMono, takeaway).flatMap(f -> {
+            return Mono.zip(groupAudio, retAudio, returnLoop, backgroupImageItemMono,takeaway).flatMap(f -> {
                 PlanNewCommonMaterialRes materialRes = new PlanNewCommonMaterialRes();
                 materialRes.setGroupAudio(f.getT1());
                 materialRes.setRetAudio(f.getT2());
@@ -591,9 +594,6 @@ public class PlanNewCommonOutController {
      */
     @PostMapping("planCommonShare")
     public Mono<RStatus<PlanNewCommonShareRes>> planCommonShare(@RequestBody PlanNewCommonShareReq request) {
-        if (request == null) {
-            return Mono.error(new BaseException("请求参数为空"));
-        }
         if (MAP.containsKey(request.getUnique())) {
             Integer integer = MAP.get(request.getUnique());
             MAP.put(request.getUnique(), integer + 1);
@@ -604,7 +604,7 @@ public class PlanNewCommonOutController {
         }
         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 BaseException("code错误::" + throwable.getMessage())));
+                .onErrorResume(throwable -> Mono.error(new Exception(LogExceptionStackTrace.erroStackTrace(throwable).toString())));
         Mono<PlanNewCommonShareRes> resMono = planNewCommonMono.flatMap(plan -> {
             Mono<StringBuilder> stringBuilderMono;
             boolean isQs = Objects.nonNull(request.getWx_user_id()) && !request.getWx_user_id().isEmpty();
@@ -644,7 +644,7 @@ public class PlanNewCommonOutController {
                             int v = userVisits % qs.size();
                             res.setQsSetting(qs.get(v));
                             if (f.getT6().toString().isEmpty()) {
-                                return Mono.error(new BaseException("计划链接 查询匹配域名为空"));
+                                throw new BaseException("计划链接 查询匹配域名为空");
                             }
                             res.setLink(f.getT6().toString());
                         } else {
@@ -666,7 +666,7 @@ public class PlanNewCommonOutController {
                             int v = userVisits % fx.size();
                             res.setFxSetting(fx.get(v));
                             if (f.getT6().toString().isEmpty()) {
-                                return Mono.error(new BaseException("计划链接 查询匹配域名为空"));
+                                throw new BaseException("计划链接 查询匹配域名为空");
                             }
                             res.setLink(f.getT6().toString());
                         } else {
@@ -720,7 +720,7 @@ public class PlanNewCommonOutController {
                 try {
                     jsonObject1 = JSONUtil.parseObj(ret);
                 } catch (Exception e) {
-                    return Mono.error(new Exception(e.getMessage() + "---" + JSONUtil.parseObj(goRequest) + " error:" + LogExceptionStackTrace.erroStackTrace(e).toString()));
+                    throw new BaseException(e.getMessage() + "---" + JSONUtil.parseObj(goRequest) + " error:" + LogExceptionStackTrace.erroStackTrace(e).toString());
                 }
                 if (jsonObject1.containsKey("code") && jsonObject1.get("code", Integer.class) == 0 && jsonObject1.containsKey("data")) {
                     JSONObject data = jsonObject1.get("data", JSONObject.class);
@@ -748,8 +748,7 @@ public class PlanNewCommonOutController {
         try {
             jsonObject = JSONUtil.parseObj(posterTemplate);
         } catch (Exception e) {
-            log.error(e.getMessage() + "---" + posterTemplate + " error:" + LogExceptionStackTrace.erroStackTrace(e).toString());
-            return null;
+            throw new BaseException(e.getMessage() + "---" + posterTemplate + " error:" + LogExceptionStackTrace.erroStackTrace(e).toString());
         }
         // JSONObject jsonObject = JSONUtil.parseObj(posterTemplate);
         GoRequest goRequest = new GoRequest();
@@ -795,7 +794,7 @@ public class PlanNewCommonOutController {
             try {
                 jsonObject = JSONUtil.parseObj(posterTemplate);
             } catch (Exception e) {
-                return Mono.error(new Exception(e.getMessage() + "---" + posterTemplate + " error:" + LogExceptionStackTrace.erroStackTrace(e).toString()));
+                throw new BaseException(e.getMessage() + "---" + posterTemplate + " error:" + LogExceptionStackTrace.erroStackTrace(e).toString());
             }
             GoRequest goRequest = new GoRequest();
             BeanUtil.copyProperties(jsonObject, goRequest);

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

@@ -22,6 +22,7 @@ import com.webflux.launchcommon.returnObj.RStatus;
 import com.weblux.launchredis.utils.RedisKey;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
+import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
@@ -73,6 +74,7 @@ public class PlanNewOutController {
 
     //清空用户Map数据
     @Scheduled(cron="1 1 4 * * ?")
+    @SchedulerLock(name = "launch:PlanNewOutController:clearUserContextMap", lockAtLeastFor = "PT5S", lockAtMostFor = "PT15M")
     public void clearUserContextMap(){
         log.info("清空计划-H5用户Map数据》》》》》》》》》》》》》》》》》》》》》》开始");
         map.clear();

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

@@ -27,6 +27,7 @@ import com.webflux.launchcommon.returnObj.Paged;
 import com.webflux.launchcommon.returnObj.RStatus;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
+import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
@@ -415,6 +416,7 @@ public class ListeningPlanServiceImpl implements ListeningPlanServiceInterface{
     private static final ConcurrentHashMap<String,Integer> map = new ConcurrentHashMap<>();
     //清空用户Map数据
     @Scheduled(cron="1 2 4 * * ?")
+    @SchedulerLock(name = "launch:ListeningPlanServiceImpl:clearUserContextMap", lockAtLeastFor = "PT5S", lockAtMostFor = "PT15M")
     public void clearUserContextMap(){
         log.info("清空听书裂变计划-H5用户Map数据》》》》》》》》》》》》》》》》》》》》》》开始");
         map.clear();

+ 2 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/task/SyncDomainToRedis.java

@@ -5,6 +5,7 @@ import com.webflux.launchadmin.mysql.entity.listening.ListeningPlanNew;
 import com.webflux.launchadmin.mysql.entity.planNew.DomainSelect;
 import com.weblux.launchredis.utils.RedisKey;
 import jakarta.annotation.Resource;
+import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
 import org.springframework.data.redis.core.StringRedisTemplate;
@@ -26,6 +27,7 @@ public class SyncDomainToRedis {
     private StringRedisTemplate stringRedisTemplate;
 
     @Scheduled(cron = "0 */1 * * * ?")
+    @SchedulerLock(name = "launch:SyncDomainToRedis:syncDomain", lockAtLeastFor = "PT5S", lockAtMostFor = "PT15M")
     public void syncDomain() {
         //.更新相信信息
         //.新增ID

+ 2 - 0
launch-admin/src/main/java/com/webflux/launchadmin/mysql/task/SyncPlanToRedis.java

@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.webflux.launchadmin.mysql.entity.listening.ListeningPlanNew;
 import com.weblux.launchredis.utils.RedisKey;
 import jakarta.annotation.Resource;
+import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
 import org.springframework.data.redis.core.StringRedisTemplate;
@@ -20,6 +21,7 @@ public class SyncPlanToRedis {
     private StringRedisTemplate stringRedisTemplate;
 
     @Scheduled(cron="0 */1 * * * ?")
+    @SchedulerLock(name = "launch:SyncPlanToRedis:syncListenBook", lockAtLeastFor = "PT5S", lockAtMostFor = "PT15M")
     public void syncListenBook(){
         Flux<ListeningPlanNew> plans = template.select(ListeningPlanNew.class).all();
         plans.toIterable().forEach(one -> {

+ 3 - 0
launch-admin/src/main/resources/application-prod.yml

@@ -6,6 +6,9 @@ spring:
       password: MidGroud_666DaTa
       database: 10
       timeout: 10000
+      jedis:
+        pool:
+          max-active: 1000
   r2dbc:
     url: r2dbcs:mysql://rm-uf6xylut5n33hb3o5.mysql.rds.aliyuncs.com:3306/wx_share_8?serverZoneId=GMT%2b8&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&ssl=false&sslMode=DISABLED
     username: wx_share_liuwei

+ 10 - 0
launch-common/pom.xml

@@ -33,6 +33,16 @@
             <artifactId>hutool-all</artifactId>
             <version>5.3.7</version>
         </dependency>
+        <dependency>
+            <groupId>net.javacrumbs.shedlock</groupId>
+            <artifactId>shedlock-spring</artifactId>
+            <version>5.1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>net.javacrumbs.shedlock</groupId>
+            <artifactId>shedlock-provider-redis-spring</artifactId>
+            <version>5.1.0</version>
+        </dependency>
 
     </dependencies>
 

+ 29 - 0
launch-common/src/main/java/com/webflux/launchcommon/config/SchedulerLock.java

@@ -0,0 +1,29 @@
+package com.webflux.launchcommon.config;
+
+import net.javacrumbs.shedlock.core.LockProvider;
+import net.javacrumbs.shedlock.provider.redis.spring.RedisLockProvider;
+import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+
+@Configuration
+@EnableSchedulerLock(defaultLockAtMostFor = "PT55S")
+public class SchedulerLock {
+    // defaultLockAtMostFor 指定在执行节点结束时应保留锁的默认时间使用ISO8601 Duration格式
+    // 作用就是在被加锁的节点挂了时,无法释放锁,造成其他节点无法进行下一任务
+    // 这里默认55s
+    // 关于ISO8601 Duration格式用的不到,具体可上网查询下相关资料,应该就是一套规范,规定一些时间表达方式
+    public class ShedLockRedisConfig {
+        @Value("${spring.profiles.active}")
+        private String env;
+
+        @Bean
+        public LockProvider lockProvider(RedisConnectionFactory connectionFactory) {
+            // 环境变量 -需要区分不同环境避免冲突,如dev环境和test环境,两者都部署时,只有一个实例进行,此时会造成相关环境未启动情况
+            System.out.println(env);
+            return new RedisLockProvider(connectionFactory, env);
+        }
+    }
+}