Explorar el Código

update 租户后台 新增课程目录是否关联商品问题

ct hace 5 días
padre
commit
a4443cf114

+ 2 - 1
fs-admin-saas/src/main/resources/application-dev.yml

@@ -6,7 +6,8 @@ spring:
     # redis 配置
     # redis 配置
     redis:
     redis:
         # 地址
         # 地址
-        host: localhost
+        #host: localhost
+        host: 172.27.0.7
         # 端口,默认为6379
         # 端口,默认为6379
         port: 6379
         port: 6379
         # 数据库索引
         # 数据库索引

+ 2 - 1
fs-admin/src/main/resources/application-dev.yml

@@ -3,7 +3,8 @@ spring:
     # redis 配置
     # redis 配置
     redis:
     redis:
         # 地址
         # 地址
-        host: localhost
+        #host: localhost
+        host: 172.27.0.7
         # 端口,默认为6379
         # 端口,默认为6379
         port: 6379
         port: 6379
         # 数据库索引
         # 数据库索引

+ 2 - 1
fs-agent/src/main/resources/application-dev.yml

@@ -6,7 +6,8 @@ spring:
     # redis 配置
     # redis 配置
     redis:
     redis:
         # 地址
         # 地址
-        host: localhost
+        #host: localhost
+        host: 172.27.0.7
         # 端口,默认为6379
         # 端口,默认为6379
         port: 6379
         port: 6379
         # 数据库索引
         # 数据库索引

+ 2 - 1
fs-company/src/main/resources/application-dev.yml

@@ -3,7 +3,8 @@ spring:
         restart:
         restart:
             enabled: false
             enabled: false
     redis:
     redis:
-        host: localhost
+        #host: localhost
+        host: 172.27.0.7
         port: 6379
         port: 6379
         password:
         password:
         database: 0
         database: 0

+ 18 - 0
fs-framework/src/main/java/com/fs/framework/config/ThreadPoolConfig.java

@@ -1,8 +1,11 @@
 package com.fs.framework.config;
 package com.fs.framework.config;
 
 
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 import org.apache.commons.lang3.concurrent.BasicThreadFactory;
 import org.apache.commons.lang3.concurrent.BasicThreadFactory;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Configuration;
@@ -59,4 +62,19 @@ public class ThreadPoolConfig
             }
             }
         };
         };
     }
     }
+
+    /**
+     * 企微 SOP 评级专用线程池(与 scheduledExecutorService 隔离,避免消费者与定时任务共用)
+     */
+    @Bean(name = "sopRatingExecutor", destroyMethod = "shutdown")
+    public ExecutorService sopRatingExecutor() {
+        return new ThreadPoolExecutor(
+                16,
+                32,
+                300L,
+                TimeUnit.SECONDS,
+                new LinkedBlockingQueue<>(800),
+                new BasicThreadFactory.Builder().namingPattern("SopRating-%d").daemon(false).build(),
+                new ThreadPoolExecutor.CallerRunsPolicy());
+    }
 }
 }

+ 1 - 0
fs-qw-api/src/main/resources/application.yml

@@ -6,6 +6,7 @@ server:
 spring:
 spring:
   profiles:
   profiles:
     active: dev
     active: dev
+    include: common,config-dev
 #    active: druid-hdt
 #    active: druid-hdt
 #    active: druid-sft
 #    active: druid-sft
 #    active: druid-myhk
 #    active: druid-myhk

+ 84 - 87
fs-service/src/main/java/com/fs/company/utils/JwtUtils.java

@@ -1,87 +1,84 @@
-//package com.fs.company.utils;
-//
-//import io.jsonwebtoken.Claims;
-//import io.jsonwebtoken.Jwts;
-//import io.jsonwebtoken.SignatureAlgorithm;
-//import org.slf4j.Logger;
-//import org.slf4j.LoggerFactory;
-//import org.springframework.boot.context.properties.ConfigurationProperties;
-//import org.springframework.stereotype.Component;
-//
-//import java.util.Date;
-//
-///**
-// * jwt工具类
-//
-// */
-//@ConfigurationProperties(prefix = "fs.jwt")
-//@Component
-//public class JwtUtils {
-//    private Logger logger = LoggerFactory.getLogger(getClass());
-//
-//
-//    private String secret;
-//    private long expire;
-//    private String header;
-//
-//    /**
-//     * 生成jwt token
-//     */
-//    public String generateToken(long userId) {
-//        Date nowDate = new Date();
-//        //过期时间
-//        Date expireDate = new Date(nowDate.getTime() + expire * 1000);
-//
-//        return Jwts.builder()
-//                .setHeaderParam("typ", "JWT")
-//                .setSubject(userId+"")
-//                .setIssuedAt(nowDate)
-//                .setExpiration(expireDate)
-//                .signWith(SignatureAlgorithm.HS512, secret)
-//                .compact();
-//    }
-//
-//    public Claims getClaimByToken(String token) {
-//        try {
-//            return Jwts.parser()
-//                    .setSigningKey(secret)
-//                    .parseClaimsJws(token)
-//                    .getBody();
-//        }catch (Exception e){
-//            logger.debug("validate is token error ", e);
-//            return null;
-//        }
-//    }
-//
-//    /**
-//     * token是否过期
-//     * @return  true:过期
-//     */
-//    public boolean isTokenExpired(Date expiration) {
-//        return expiration.before(new Date());
-//    }
-//
-//    public String getSecret() {
-//        return secret;
-//    }
-//
-//    public void setSecret(String secret) {
-//        this.secret = secret;
-//    }
-//
-//    public long getExpire() {
-//        return expire;
-//    }
-//
-//    public void setExpire(long expire) {
-//        this.expire = expire;
-//    }
-//
-//    public String getHeader() {
-//        return header;
-//    }
-//
-//    public void setHeader(String header) {
-//        this.header = header;
-//    }
-//}
+package com.fs.company.utils;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+/**
+ * jwt工具类
+ */
+@ConfigurationProperties(prefix = "fs.jwt")
+@Component
+public class JwtUtils {
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+    private String secret;
+    private long expire;
+    private String header;
+
+    /**
+     * 生成jwt token
+     */
+    public String generateToken(long userId) {
+        Date nowDate = new Date();
+        Date expireDate = new Date(nowDate.getTime() + expire * 1000);
+
+        return Jwts.builder()
+                .setHeaderParam("typ", "JWT")
+                .setSubject(userId + "")
+                .setIssuedAt(nowDate)
+                .setExpiration(expireDate)
+                .signWith(SignatureAlgorithm.HS512, secret)
+                .compact();
+    }
+
+    public Claims getClaimByToken(String token) {
+        try {
+            return Jwts.parser()
+                    .setSigningKey(secret)
+                    .parseClaimsJws(token)
+                    .getBody();
+        } catch (Exception e) {
+            logger.debug("validate is token error ", e);
+            return null;
+        }
+    }
+
+    /**
+     * token是否过期
+     * @return true:过期
+     */
+    public boolean isTokenExpired(Date expiration) {
+        return expiration.before(new Date());
+    }
+
+    public String getSecret() {
+        return secret;
+    }
+
+    public void setSecret(String secret) {
+        this.secret = secret;
+    }
+
+    public long getExpire() {
+        return expire;
+    }
+
+    public void setExpire(long expire) {
+        this.expire = expire;
+    }
+
+    public String getHeader() {
+        return header;
+    }
+
+    public void setHeader(String header) {
+        this.header = header;
+    }
+}

+ 5 - 3
fs-service/src/main/java/com/fs/qwApi/config/OpenQwConfig.java

@@ -1,8 +1,10 @@
 package com.fs.qwApi.config;
 package com.fs.qwApi.config;
 
 
 public interface OpenQwConfig {
 public interface OpenQwConfig {
-    String baseApi ="http://saasqwapi.ylrzcloud.com/open/qwapi";
+    String baseApi ="http://newsaasqwapi.ylrzcloud.com/open/qwapi";
 //    String baseApi ="http://127.0.0.1:8007/open/qwapi";
 //    String baseApi ="http://127.0.0.1:8007/open/qwapi";
-    String api ="http://saasqwapi.ylrzcloud.com";
-    String taskApi ="192.168.0.64:7006";
+    String api ="http://newsaasqwapi.ylrzcloud.com";
+//    String api ="http://127.0.0.1:8007";
+//    String taskApi ="192.168.0.64:7006";
+    String taskApi ="127.0.0.1:7006";
 }
 }

+ 2 - 2
fs-service/src/main/resources/application-dev.yml

@@ -3,8 +3,8 @@ spring:
     # redis 配置
     # redis 配置
     redis:
     redis:
         # 地址
         # 地址
-        host: localhost
-#        host: 192.168.0.245
+        #host: localhost
+        host: 172.27.0.7
         # 端口,默认为6379
         # 端口,默认为6379
         port: 6379
         port: 6379
         # 数据库索引
         # 数据库索引

+ 12 - 31
fs-task/src/main/java/com/fs/app/taskService/impl/QwExternalContactRatingMoreSevenDaysServiceImpl.java

@@ -21,6 +21,7 @@ import com.fs.system.service.ISysConfigService;
 import com.fs.voice.utils.StringUtil;
 import com.fs.voice.utils.StringUtil;
 import com.google.common.util.concurrent.AtomicDouble;
 import com.google.common.util.concurrent.AtomicDouble;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
@@ -69,7 +70,8 @@ public class QwExternalContactRatingMoreSevenDaysServiceImpl implements QwExtern
     private ISopUserLogsInfoService iSopUserLogsInfoService;
     private ISopUserLogsInfoService iSopUserLogsInfoService;
 
 
     @Autowired
     @Autowired
-    private ExecutorService sopRatingExecutor;  // 自定义线程池
+    @Qualifier("sopRatingExecutor")
+    private ExecutorService sopRatingExecutor;
 
 
     @Resource
     @Resource
     private TenantTaskRunner tenantTaskRunner;
     private TenantTaskRunner tenantTaskRunner;
@@ -169,12 +171,15 @@ public class QwExternalContactRatingMoreSevenDaysServiceImpl implements QwExtern
             return; // 如果队列为空且没有正在运行的线程,则直接返回
             return; // 如果队列为空且没有正在运行的线程,则直接返回
         }
         }
 
 
-        while (running) {
+        while (running && !Thread.currentThread().isInterrupted()) {
             try {
             try {
-                SopUserLogs item = taskQueue.poll(1, TimeUnit.SECONDS); // 等待 1 秒
+                SopUserLogs item = taskQueue.poll(1, TimeUnit.SECONDS);
                 if (item != null) {
                 if (item != null) {
                     processSingleTask(item);
                     processSingleTask(item);
                 }
                 }
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                break;
             } catch (Exception e) {
             } catch (Exception e) {
                 log.error("消费者线程异常", e);
                 log.error("消费者线程异常", e);
             }
             }
@@ -272,35 +277,11 @@ public class QwExternalContactRatingMoreSevenDaysServiceImpl implements QwExtern
 
 
     @PreDestroy
     @PreDestroy
     public void shutdown() {
     public void shutdown() {
-        running = false;  // 标记消费者停止
-        log.info("正在关闭线程池...");
-
-        // **等待任务队列处理完毕**
-        while (!taskQueue.isEmpty()) {
-            try {
-                Thread.sleep(500);
-            } catch (InterruptedException e) {
-                Thread.currentThread().interrupt();
-                log.warn("等待任务队列处理完成时被中断", e);
-            }
-        }
-
-        // **确保所有 `batchUpdateQwExternalContact` 的任务完成**
-        log.info("等待所有批量更新任务完成...");
-        CompletableFuture.allOf(updateFutures.toArray(new CompletableFuture[0])).join();
-
-        // 关闭线程池
-        sopRatingExecutor.shutdown();
-        try {
-            if (!sopRatingExecutor.awaitTermination(60, TimeUnit.SECONDS)) {
-                List<Runnable> pendingTasks = sopRatingExecutor.shutdownNow();
-                log.warn("强制关闭线程池,未完成任务数: {}", pendingTasks.size());
-            }
-        } catch (InterruptedException e) {
-            sopRatingExecutor.shutdownNow();
-            Thread.currentThread().interrupt();
+        running = false;
+        log.info("7天未看课评级消费者停止中...");
+        if (!updateFutures.isEmpty()) {
+            CompletableFuture.allOf(updateFutures.toArray(new CompletableFuture[0])).join();
         }
         }
-        log.info("线程池和消费者已完全关闭");
     }
     }
 
 
 
 

+ 12 - 31
fs-task/src/main/java/com/fs/app/taskService/impl/QwExternalContactRatingServiceImpl.java

@@ -21,6 +21,7 @@ import com.fs.system.service.ISysConfigService;
 import com.fs.voice.utils.StringUtil;
 import com.fs.voice.utils.StringUtil;
 import com.google.common.util.concurrent.AtomicDouble;
 import com.google.common.util.concurrent.AtomicDouble;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
@@ -70,7 +71,8 @@ public class QwExternalContactRatingServiceImpl implements QwExternalContactRati
     private ISopUserLogsInfoService iSopUserLogsInfoService;
     private ISopUserLogsInfoService iSopUserLogsInfoService;
 
 
     @Autowired
     @Autowired
-    private ExecutorService sopRatingExecutor;  // 自定义线程池
+    @Qualifier("sopRatingExecutor")
+    private ExecutorService sopRatingExecutor;
 
 
     @Resource
     @Resource
     private TenantTaskRunner tenantTaskRunner;
     private TenantTaskRunner tenantTaskRunner;
@@ -162,12 +164,15 @@ public class QwExternalContactRatingServiceImpl implements QwExternalContactRati
             return; // 如果队列为空且没有正在运行的线程,则直接返回
             return; // 如果队列为空且没有正在运行的线程,则直接返回
         }
         }
 
 
-        while (running) {
+        while (running && !Thread.currentThread().isInterrupted()) {
             try {
             try {
-                SopUserLogs item = taskQueue.poll(1, TimeUnit.SECONDS); // 等待 1 秒
+                SopUserLogs item = taskQueue.poll(1, TimeUnit.SECONDS);
                 if (item != null) {
                 if (item != null) {
                     processSingleTask(item);
                     processSingleTask(item);
                 }
                 }
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                break;
             } catch (Exception e) {
             } catch (Exception e) {
                 log.error("消费者线程异常", e);
                 log.error("消费者线程异常", e);
             }
             }
@@ -273,35 +278,11 @@ public class QwExternalContactRatingServiceImpl implements QwExternalContactRati
 
 
     @PreDestroy
     @PreDestroy
     public void shutdown() {
     public void shutdown() {
-        running = false;  // 标记消费者停止
-        log.info("正在关闭线程池...");
-
-        // **等待任务队列处理完毕**
-        while (!taskQueue.isEmpty()) {
-            try {
-                Thread.sleep(500);
-            } catch (InterruptedException e) {
-                Thread.currentThread().interrupt();
-                log.warn("等待任务队列处理完成时被中断", e);
-            }
-        }
-
-        // **确保所有 `batchUpdateQwExternalContact` 的任务完成**
-        log.info("等待所有批量更新任务完成...");
-        CompletableFuture.allOf(updateFutures.toArray(new CompletableFuture[0])).join();
-
-        // 关闭线程池
-        sopRatingExecutor.shutdown();
-        try {
-            if (!sopRatingExecutor.awaitTermination(60, TimeUnit.SECONDS)) {
-                List<Runnable> pendingTasks = sopRatingExecutor.shutdownNow();
-                log.warn("强制关闭线程池,未完成任务数: {}", pendingTasks.size());
-            }
-        } catch (InterruptedException e) {
-            sopRatingExecutor.shutdownNow();
-            Thread.currentThread().interrupt();
+        running = false;
+        log.info("企微评级消费者停止中...");
+        if (!updateFutures.isEmpty()) {
+            CompletableFuture.allOf(updateFutures.toArray(new CompletableFuture[0])).join();
         }
         }
-        log.info("线程池和消费者已完全关闭");
     }
     }
 
 
 
 

+ 12 - 31
fs-task/src/main/java/com/fs/app/taskService/impl/SopUserLogsInfoByIsDaysNotStudyImpl.java

@@ -13,6 +13,7 @@ import com.fs.sop.service.ISopUserLogsService;
 import com.fs.system.service.ISysConfigService;
 import com.fs.system.service.ISysConfigService;
 import com.fs.voice.utils.StringUtil;
 import com.fs.voice.utils.StringUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
 import javax.annotation.PostConstruct;
 import javax.annotation.PostConstruct;
@@ -47,7 +48,8 @@ public class SopUserLogsInfoByIsDaysNotStudyImpl implements SopUserLogsInfoByIsD
     private ISopUserLogsService iSopUserLogsService;
     private ISopUserLogsService iSopUserLogsService;
 
 
     @Autowired
     @Autowired
-    private ExecutorService sopRatingExecutor;  // 自定义线程池
+    @Qualifier("sopRatingExecutor")
+    private ExecutorService sopRatingExecutor;
 
 
     // 任务队列
     // 任务队列
     private final BlockingQueue<SopUserLogs> taskQueue = new LinkedBlockingQueue<>(10000);
     private final BlockingQueue<SopUserLogs> taskQueue = new LinkedBlockingQueue<>(10000);
@@ -141,12 +143,15 @@ public class SopUserLogsInfoByIsDaysNotStudyImpl implements SopUserLogsInfoByIsD
             return; // 如果队列为空且没有正在运行的线程,则直接返回
             return; // 如果队列为空且没有正在运行的线程,则直接返回
         }
         }
 
 
-        while (running) {
+        while (running && !Thread.currentThread().isInterrupted()) {
             try {
             try {
-                SopUserLogs item = taskQueue.poll(1, TimeUnit.SECONDS); // 等待 1 秒
+                SopUserLogs item = taskQueue.poll(1, TimeUnit.SECONDS);
                 if (item != null) {
                 if (item != null) {
                     processRestoreByIsDaysNotStudy(item);
                     processRestoreByIsDaysNotStudy(item);
                 }
                 }
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                break;
             } catch (Exception e) {
             } catch (Exception e) {
                 log.error("消费者线程异常", e);
                 log.error("消费者线程异常", e);
             }
             }
@@ -200,35 +205,11 @@ public class SopUserLogsInfoByIsDaysNotStudyImpl implements SopUserLogsInfoByIsD
 
 
     @PreDestroy
     @PreDestroy
     public void shutdown() {
     public void shutdown() {
-        running = false;  // 标记消费者停止
-        log.info("正在关闭线程池...");
-
-        // **等待任务队列处理完毕**
-        while (!taskQueue.isEmpty()) {
-            try {
-                Thread.sleep(500);
-            } catch (InterruptedException e) {
-                Thread.currentThread().interrupt();
-                log.warn("等待任务队列处理完成时被中断", e);
-            }
-        }
-
-        // **确保所有  的任务完成**
-        log.info("等待所有批量更新任务完成...");
-        CompletableFuture.allOf(updateFutures.toArray(new CompletableFuture[0])).join();
-
-        // 关闭线程池
-        sopRatingExecutor.shutdown();
-        try {
-            if (!sopRatingExecutor.awaitTermination(60, TimeUnit.SECONDS)) {
-                List<Runnable> pendingTasks = sopRatingExecutor.shutdownNow();
-                log.warn("强制关闭线程池,未完成任务数: {}", pendingTasks.size());
-            }
-        } catch (InterruptedException e) {
-            sopRatingExecutor.shutdownNow();
-            Thread.currentThread().interrupt();
+        running = false;
+        log.info("E级客户恢复消费者停止中...");
+        if (!updateFutures.isEmpty()) {
+            CompletableFuture.allOf(updateFutures.toArray(new CompletableFuture[0])).join();
         }
         }
-        log.info("线程池和消费者已完全关闭");
     }
     }
 
 
     /**
     /**

+ 11 - 0
fs-task/src/main/resources/application-common.yml

@@ -58,7 +58,18 @@ mybatis-plus:
   configuration:
   configuration:
     mapUnderscoreToCamelCase: true
     mapUnderscoreToCamelCase: true
     log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
     log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+wechat:
+  api:
+    base-url: https://api.weixin.qq.com
+    upload-shipping-info: /wxa/sec/order/upload_shipping_info
+express:
+  omsCode: "SF.0235402855"
+baidu:
+  token: 12313231232
+  back-domain: https://www.xxxx.com
 
 
 # 租户相关
 # 租户相关
 tenant:
 tenant:
   enabled: true
   enabled: true
+
+

+ 2 - 1
fs-task/src/main/resources/application-dev.yml

@@ -2,7 +2,8 @@
 spring:
 spring:
     # redis 配置
     # redis 配置
     redis:
     redis:
-        host: localhost
+        #host: localhost
+        host: 172.27.0.7
         port: 6379
         port: 6379
         database: 0
         database: 0
         password:
         password:

+ 2 - 2
fs-user-app/src/main/resources/application-dev.yml

@@ -7,8 +7,8 @@ spring:
 #    # redis 配置
 #    # redis 配置
     redis:
     redis:
         # 地址
         # 地址
-        host: localhost
-#        host: 192.168.0.245
+        #host: localhost
+        host: 172.27.0.7
         # 端口,默认为6379
         # 端口,默认为6379
         port: 6379
         port: 6379
         # 数据库索引
         # 数据库索引

+ 4 - 4
fs-wx-api/src/main/resources/application-common.yml

@@ -14,12 +14,12 @@ fs:
   addressEnabled: false
   addressEnabled: false
   # 验证码类型 math 数组计算 char 字符验证
   # 验证码类型 math 数组计算 char 字符验证
   captchaType: math
   captchaType: math
-#  jwt:
+  jwt:
 #    # 加密秘钥
 #    # 加密秘钥
-#    secret: f4e2e52034348f86b67cde581c0f9eb5
+    secret: f4e2e52034348f86b67cde581c0f9eb5
 #    # token有效时长,7天,单位秒
 #    # token有效时长,7天,单位秒
-#    expire: 31536000
-#    header: AppToken
+    expire: 31536000
+    header: AppToken
 # 开发环境配置
 # 开发环境配置
 server:
 server:
   servlet:
   servlet:

+ 1 - 1
fs-wx-ipad-task/pom.xml

@@ -117,7 +117,7 @@
             <plugin>
             <plugin>
                 <groupId>org.springframework.boot</groupId>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
-                <version>2.1.1.RELEASE</version>
+                <version>2.7.18</version>
                 <configuration>
                 <configuration>
                     <fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
                     <fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
                 </configuration>
                 </configuration>