“mitao”
2026-04-10 ff81ea1b22aa35776012233f0e3c8b4073faee69
Merge remote-tracking branch 'origin/master'
14个文件已删除
5个文件已添加
9个文件已修改
2093 ■■■■■ 已修改文件
.gitignore 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/resources/application-local.yml 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpPointServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/pom.xml 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/DecodingException.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/TrafficControlApplication.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/config/DataUpdateHandlerConfig.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/config/MessageLocalConfig.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/config/MultipartFilterConfig.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/config/MyLocaleResolver.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/config/MybatisPlusConfig.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/config/TransactionConfiguration.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/config/log/FeignLoggingAspect.java 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/config/log/RequestResponseLoggingFilter.java 315 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/constant/I18nKeyConstant.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/controller/HttpTestController.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/enums/SignatureType.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/util/HMACSHA1.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/util/HexUtil.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/util/ResourceUtil.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/util/SHA1Util.java 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/util/SignatureUtils.java 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/util/ThreadLocalSHA1.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/utils/MinistryOfTransport.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/resources/application-local.yml 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/resources/bootstrap.yml 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-traffic-control-boot/src/main/resources/logback.xml.bak 222 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
@@ -15,7 +15,7 @@
target
*.yaml
*.yml
#*.yaml
#*.yml
*.log.DS_Store
**/.DS_Store
xp-robotaxi-itinerary-boot/src/main/resources/application-local.yml
New file
@@ -0,0 +1,108 @@
spring:
  config:
    activate:
      on-profile: local
  autoconfigure:
    exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
  redis:
    database: 99
    host: r-bp1ip8die60uuo3ovypd.redis.rds.aliyuncs.com
    password: syAktm2x9uDusoF_
    port: 6379
  data:
    mongodb:
      host: dds-bp1f4a38f3cccad4-pub.mongodb.rds.aliyuncs.com
      port: 3717
      database: xp_robotaxi
      username: xp_robotaxi
      password: hDXSBe_hs0d5KxUf
  shardingsphere:
    datasource:
      names: xp0
      xp0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://pc-bp1o444934f546768po.rwlb.rds.aliyuncs.com:3306/xp_rt_order?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: xp_rt_order
        password: JLZtAI_BL4Lv5mbE
        druid:
          initial-size: 10
          min-idle: 10
          max-active: 100
          max-wait: 60000
          time-between-eviction-runs-millis: 60000
          min-evictable-idle-time-millis: 300000
          validation-query: SELECT 1
          test-while-idle: true
          test-on-borrow: false
          test-on-return: false
          pool-prepared-statements: true
          max-pool-prepared-statement-per-connection-size: 20
          filters: stat,wall,log4j
          connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
          remove-abandoned: true
          remove-abandoned-timeout: 1800
          log-abandoned: true
          stat-view-servlet:
            enabled: true
            url-pattern: /druid/*
            login-username: admin
            login-password: admin
            reset-enable: false
          wall:
            config:
              multi-statement-allow: false
    rules:
      sharding:
        tables:
          sys_oper_log:
            actual-data-nodes: xp0.sys_oper_log_${0..9}
            table-strategy:
              standard:
                sharding-column: userId
                sharding-algorithm-name: sys-oper-log-inline
            key-generate-strategy:
              column: oper_id
              key-generator-name: snowflake
          xp_agreement_app_user:
            actual-data-nodes: xp0.xp_agreement_app_user_${0..9}
            table-strategy:
              standard:
                sharding-column: app_user_id
                sharding-algorithm-name: xp-agreement-app-user-inline
            key-generate-strategy:
              column: id
              key-generator-name: snowflake
          xp_point:
            actual-data-nodes: xp0.xp_point_${0..9}
            table-strategy:
              standard:
                sharding-column: electronic_area_id
                sharding-algorithm-name: xp-point-inline
            key-generate-strategy:
              column: id
              key-generator-name: snowflake
        sharding-algorithms:
          sys-oper-log-inline:
            type: INLINE
            props:
              algorithm-expression: sys_oper_log_${userId % 10}
          xp-agreement-app-user-inline:
            type: INLINE
            props:
              algorithm-expression: xp_agreement_app_user_${app_user_id % 10}
          xp-point-inline:
            type: INLINE
            props:
              algorithm-expression: xp_point_${electronic_area_id % 10}
        key-generators:
          snowflake:
            type: SNOWFLAKE
      single-table:
        default-data-source-name: xp0
    props:
      sql-show: true
      sql-simple: true
seata:
  enabled: false
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpPointServiceImpl.java
@@ -303,7 +303,10 @@
        List<XpPoint> list = this.baseMapper.listAll(query);
        for (XpPoint xpPoint : list) {
            String pointPictures = xpPoint.getPointPictures();
            log.info("pointPictures:{}", pointPictures);
            if (StringUtils.isNotBlank(pointPictures)) {
                log.info("pointPictures进入处理:{}", pointPictures);
                JSONArray jsonArray = JSONArray.parseArray(pointPictures);
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
@@ -313,12 +316,15 @@
                    String downloadUrl ="";
                    try {
                        downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                        log.info("downloadUrl:{}", downloadUrl);
                    } catch (UnsupportedEncodingException e) {
                        log.error("获取图片下载地址失败", e);
                    }
                    jsonObject.put("url", downloadUrl);
                }
                log.info("jsonArray:{}", jsonArray);
                xpPoint.setPointPictures(JSONArray.toJSONString(jsonArray));
                log.info("xpPoint:{}", xpPoint.getPointPictures());
            }
        }
xp-robotaxi-traffic-control-boot/pom.xml
@@ -127,53 +127,6 @@
            <artifactId>log4j-core</artifactId>
            <version>2.25.3</version>
        </dependency>
        <!-- easypoi -->
        <!-- Apache POI 核心依赖 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>5.2.3</version>
        </dependency>
        <!-- Apache POI OOXML 支持(用于 .xlsx 文件) -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.2.3</version>
        </dependency>
        <!-- Apache POI XMLBeans(可选,用于复杂 XML 处理) -->
        <dependency>
            <groupId>org.apache.xmlbeans</groupId>
            <artifactId>xmlbeans</artifactId>
            <version>5.1.1</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-base</artifactId>
            <version>4.4.0</version>
            <exclusions>
                <exclusion>
                    <artifactId>guava</artifactId>
                    <groupId>com.google.guava</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-web</artifactId>
            <version>4.4.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-annotation</artifactId>
            <version>4.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.xiaopeng.logan</groupId>
            <artifactId>xp-evi-oss-sdk</artifactId>
            <version>1.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
    <build>
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/DecodingException.java
File was deleted
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/TrafficControlApplication.java
@@ -3,24 +3,20 @@
import com.xiaopeng.common.security.annotation.EnableCustomConfig;
import com.xiaopeng.common.security.annotation.EnableRyFeignClients;
import com.xiaopeng.common.swagger.annotation.EnableCustomSwagger2;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
 * 交通监管模块
 */
@EnableCustomConfig
@MapperScan({"com.xiaopeng.trafficControl.mapper"})
@EnableCustomSwagger2
@EnableRyFeignClients
@SpringBootApplication
@EnableScheduling//开启定时任务
@EnableScheduling
@ServletComponentScan
@EnableTransactionManagement//开启事务
public class TrafficControlApplication {
    public static void main(String[] args) {
        SpringApplication.run(TrafficControlApplication.class, args);
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/config/DataUpdateHandlerConfig.java
File was deleted
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/config/MessageLocalConfig.java
@@ -6,7 +6,6 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
@@ -17,6 +16,7 @@
 */
@Configuration
public class MessageLocalConfig {
    @Bean
    public MessageSourceProperties messageSourceProperties() {
@@ -29,6 +29,7 @@
        properties.setUseCodeAsDefaultMessage(true);
        return properties;
    }
    @Bean
    public MessageSource messageSource(MessageSourceProperties properties) {
@@ -51,9 +52,9 @@
    }
    @Bean//注册国际化组件
    public LocaleResolver localeResolver(){
        return new MyLocaleResolver();
    }
//    @Bean//注册国际化组件
//    public LocaleResolver localeResolver(){
//        return new MyLocaleResolver();
//    }
}
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/config/MultipartFilterConfig.java
File was deleted
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/config/MyLocaleResolver.java
@@ -27,12 +27,10 @@
        }
        //如果请求不为空
        //If the request is not empty.
        if(!StringUtils.isEmpty(language)){
            if (language.equals("1")) {
                locale = new Locale("zh", "CN");
            } else if (language.equals("2")) {
                locale = new Locale("en", "US");
            }
        if (language.equals("1")) {
            locale = new Locale("zh", "CN");
        } else if (language.equals("2")) {
            locale = new Locale("en", "US");
        }
        return locale;
    }
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/config/MybatisPlusConfig.java
File was deleted
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/config/TransactionConfiguration.java
File was deleted
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/config/log/FeignLoggingAspect.java
@@ -1,83 +1,138 @@
package com.xiaopeng.trafficControl.config.log;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
 * Feign 调用日志切面
 *
 * <p>拦截所有带 @FeignClient 注解的接口方法,记录:
 * <ul>
 *   <li>调用的接口类名 + 方法名</li>
 *   <li>入参(JSON 序列化)</li>
 *   <li>出参(JSON 序列化)</li>
 *   <li>耗时(ms)</li>
 *   <li>异常信息(含完整堆栈)</li>
 * </ul>
 */
@Slf4j
@Aspect
@Component
public class FeignLoggingAspect {
    /**
     * 拦截所有带 @FeignClient 注解的接口的所有方法
     */
    @Around("within(@org.springframework.cloud.openfeign.FeignClient *)")
    public Object logFeignCall(ProceedingJoinPoint pjp) throws Throwable {
        return doLog(pjp);
    }
    private Object doLog(ProceedingJoinPoint pjp) throws Throwable {
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        // 使用接口声明类名,避免打印动态代理类名(如 $Proxy270)
        String className = signature.getDeclaringType().getSimpleName();
        String methodName = method.getName();
        String fullMethod = className + "#" + methodName;
        Object[] args = pjp.getArgs();
        String argsJson = safeToJson(args);
        log.info("[Feign] >>> 调用开始 | method={} | args={}", fullMethod, argsJson);
        long start = System.currentTimeMillis();
        try {
            Object result = pjp.proceed();
            long elapsed = System.currentTimeMillis() - start;
            String resultJson = safeToJson(result);
            log.info("[Feign] <<< 调用成功 | method={} | elapsed={}ms | result={}", fullMethod, elapsed, resultJson);
            return result;
        } catch (Throwable ex) {
            long elapsed = System.currentTimeMillis() - start;
            log.error("[Feign] <<< 调用异常 | method={} | elapsed={}ms | error={} | args={}",
                    fullMethod, elapsed, ex.getMessage(), argsJson, ex);
            throw ex;
        }
    }
    /**
     * 安全序列化为 JSON,避免序列化失败导致日志切面本身抛异常
     */
    private String safeToJson(Object obj) {
        if (obj == null) {
            return "null";
        }
        try {
            if (obj instanceof Object[]) {
                return JSON.toJSONString(Arrays.asList((Object[]) obj));
            }
            return JSON.toJSONString(obj);
        } catch (Exception e) {
            return "[序列化失败: " + obj.getClass().getSimpleName() + "]";
        }
    }
}
//package com.xiaopeng.trafficControl.config.log;
//
//import com.alibaba.fastjson2.JSON;
//import com.xiaopeng.common.log.config.LogHeaderProperties;
//import lombok.extern.slf4j.Slf4j;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.annotation.Around;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.reflect.MethodSignature;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//import org.springframework.web.context.request.RequestContextHolder;
//import org.springframework.web.context.request.ServletRequestAttributes;
//
//import javax.servlet.http.HttpServletRequest;
//import java.lang.reflect.Method;
//import java.util.Arrays;
//import java.util.Enumeration;
//import java.util.List;
//
///**
// * Feign 调用日志切面
// *
// * <p>拦截所有带 @FeignClient 注解的接口方法,记录:
// * <ul>
// *   <li>调用的接口类名 + 方法名</li>
// *   <li>入参(JSON 序列化)</li>
// *   <li>出参(JSON 序列化)</li>
// *   <li>耗时(ms)</li>
// *   <li>异常信息(含完整堆栈)</li>
// * </ul>
// */
//@Slf4j
//@Aspect
//@Component
//public class FeignLoggingAspect {
//
//    @Autowired
//    private LogHeaderProperties logHeaderProperties;
//
//    /**
//     * 拦截所有带 @FeignClient 注解的接口的所有方法
//     */
//    @Around("within(@org.springframework.cloud.openfeign.FeignClient *)")
//    public Object logFeignCall(ProceedingJoinPoint pjp) throws Throwable {
//        return doLog(pjp);
//    }
//
//    private Object doLog(ProceedingJoinPoint pjp) throws Throwable {
//        MethodSignature signature = (MethodSignature) pjp.getSignature();
//        Method method = signature.getMethod();
//        // 使用接口声明类名,避免打印动态代理类名(如 $Proxy270)
//        String className = signature.getDeclaringType().getSimpleName();
//        String methodName = method.getName();
//        String fullMethod = className + "#" + methodName;
//
//        Object[] args = pjp.getArgs();
//        String argsJson = safeToJson(args);
//        String headerStr = extractCurrentHeaders();
//
//        if (headerStr != null) {
//            log.info("[Feign] >>> 调用开始 | method={} | headers={} | args={}", fullMethod, headerStr, argsJson);
//        } else {
//            log.info("[Feign] >>> 调用开始 | method={} | args={}", fullMethod, argsJson);
//        }
//
//        long start = System.currentTimeMillis();
//        try {
//            Object result = pjp.proceed();
//            long elapsed = System.currentTimeMillis() - start;
//            String resultJson = safeToJson(result);
//            log.info("[Feign] <<< 调用成功 | method={} | elapsed={}ms | result={}", fullMethod, elapsed, resultJson);
//            return result;
//        } catch (Throwable ex) {
//            long elapsed = System.currentTimeMillis() - start;
//            log.error("[Feign] <<< 调用异常 | method={} | elapsed={}ms | error={} | args={}",
//                    fullMethod, elapsed, ex.getMessage(), argsJson, ex);
//            throw ex;
//        }
//    }
//
//    /**
//     * 安全序列化为 JSON,避免序列化失败导致日志切面本身抛异常
//     */
//    private String safeToJson(Object obj) {
//        if (obj == null) {
//            return "null";
//        }
//        try {
//            if (obj instanceof Object[]) {
//                return JSON.toJSONString(Arrays.asList((Object[]) obj));
//            }
//            return JSON.toJSONString(obj);
//        } catch (Exception e) {
//            return "[序列化失败: " + obj.getClass().getSimpleName() + "]";
//        }
//    }
//
//    /**
//     * 从当前请求上下文中提取请求头信息
//     */
//    private String extractCurrentHeaders() {
//        if (!logHeaderProperties.isEnabled()) {
//            return null;
//        }
//        try {
//            ServletRequestAttributes attrs = (ServletRequestAttributes)
//                    RequestContextHolder.getRequestAttributes();
//            if (attrs == null) return "{}";
//            HttpServletRequest request = attrs.getRequest();
//            List<String> names = logHeaderProperties.getNames();
//            StringBuilder sb = new StringBuilder("{");
//            boolean first = true;
//            if (names != null && !names.isEmpty()) {
//                for (String name : names) {
//                    String value = request.getHeader(name);
//                    if (value != null) {
//                        if (!first) sb.append(", ");
//                        first = false;
//                        sb.append(name).append("=").append(value);
//                    }
//                }
//            } else {
//                Enumeration<String> headerNames = request.getHeaderNames();
//                while (headerNames != null && headerNames.hasMoreElements()) {
//                    String name = headerNames.nextElement();
//                    String value = request.getHeader(name);
//                    if (!first) sb.append(", ");
//                    first = false;
//                    sb.append(name).append("=").append(value);
//                }
//            }
//            return sb.append("}").toString();
//        } catch (Exception e) {
//            return "{error: " + e.getMessage() + "}";
//        }
//    }
//}
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/config/log/RequestResponseLoggingFilter.java
@@ -1,139 +1,176 @@
package com.xiaopeng.trafficControl.config.log;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
 * 请求/响应日志过滤器
 * 打印:traceId、method、uri、queryString、请求体、响应状态、耗时、响应体
 */
@Slf4j
@Component
@Order(Ordered.HIGHEST_PRECEDENCE + 10)
public class RequestResponseLoggingFilter extends OncePerRequestFilter {
    /** 不打印 body 的路径前缀(健康检查、actuator 等) */
    private static final Set<String> EXCLUDE_PATHS = new HashSet<>(Arrays.asList(
            "/actuator", "/healthcheck", "/health", "/prometheus"
    ));
    /** 只对这些 Content-Type 打印 body(避免打印二进制流) */
    private static final Set<String> LOGGABLE_CONTENT_TYPES = new HashSet<>(Arrays.asList(
            MediaType.APPLICATION_JSON_VALUE,
            MediaType.APPLICATION_JSON_UTF8_VALUE,
            MediaType.TEXT_PLAIN_VALUE,
            MediaType.TEXT_XML_VALUE,
            MediaType.APPLICATION_XML_VALUE,
            "application/x-www-form-urlencoded"
    ));
    private static final int MAX_BODY_LENGTH = 2000;
    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) {
        String uri = request.getRequestURI();
        return EXCLUDE_PATHS.stream().anyMatch(uri::startsWith);
    }
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain chain) throws ServletException, IOException {
        // 初始化 MDC(Filter 先于 Interceptor 执行,在此统一设置)
        String traceId = request.getHeader("X-Trace-Id");
        if (traceId == null || traceId.isEmpty()) {
            traceId = java.util.UUID.randomUUID().toString().replace("-", "");
        }
        MDC.put("traceId",    traceId);
        MDC.put("clientIp",   getClientIp(request));
        MDC.put("requestUri", request.getRequestURI());
        response.setHeader("X-Trace-Id", traceId);
        ContentCachingRequestWrapper reqWrapper  = new ContentCachingRequestWrapper(request);
        ContentCachingResponseWrapper respWrapper = new ContentCachingResponseWrapper(response);
        long start = System.currentTimeMillis();
        try {
            chain.doFilter(reqWrapper, respWrapper);
        } finally {
            long cost = System.currentTimeMillis() - start;
            logRequest(reqWrapper);
            logResponse(respWrapper, cost);
            // 必须把响应体写回,否则客户端收不到数据
            respWrapper.copyBodyToResponse();
            MDC.clear();
        }
    }
    private String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip != null && !ip.isEmpty() && !"unknown".equalsIgnoreCase(ip)) {
            return ip.split(",")[0].trim();
        }
        ip = request.getHeader("X-Real-IP");
        if (ip != null && !ip.isEmpty() && !"unknown".equalsIgnoreCase(ip)) {
            return ip;
        }
        return request.getRemoteAddr();
    }
    private void logRequest(ContentCachingRequestWrapper request) {
        String traceId = MDC.get("traceId");
        String uri     = request.getRequestURI();
        String query   = request.getQueryString();
        String method  = request.getMethod();
        String body    = extractBody(request.getContentAsByteArray(), request.getContentType());
        log.info(">>> [{}] {} {}{} | body={}",
                traceId,
                method,
                uri,
                query != null ? "?" + query : "",
                body);
    }
    private void logResponse(ContentCachingResponseWrapper response, long cost) {
        String traceId = MDC.get("traceId");
        int    status  = response.getStatus();
        String body    = extractBody(response.getContentAsByteArray(), response.getContentType());
        log.info("<<< [{}] status={} cost={}ms | body={}",
                traceId, status, cost, body);
    }
    private String extractBody(byte[] bodyBytes, String contentType) {
        if (bodyBytes == null || bodyBytes.length == 0) {
            return "";
        }
        if (!isLoggableContentType(contentType)) {
            return "[binary, " + bodyBytes.length + " bytes]";
        }
        String body = new String(bodyBytes, StandardCharsets.UTF_8);
        if (body.length() > MAX_BODY_LENGTH) {
            body = body.substring(0, MAX_BODY_LENGTH) + "...(truncated)";
        }
        return body;
    }
    private boolean isLoggableContentType(String contentType) {
        if (contentType == null) return true;
        String ct = contentType.toLowerCase();
        return LOGGABLE_CONTENT_TYPES.stream().anyMatch(ct::contains);
    }
}
//package com.xiaopeng.trafficControl.config.log;
//
//import com.xiaopeng.common.log.config.LogHeaderProperties;
//import lombok.extern.slf4j.Slf4j;
//import org.slf4j.MDC;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.core.Ordered;
//import org.springframework.core.annotation.Order;
//import org.springframework.http.MediaType;
//import org.springframework.stereotype.Component;
//import org.springframework.web.filter.OncePerRequestFilter;
//import org.springframework.web.util.ContentCachingRequestWrapper;
//import org.springframework.web.util.ContentCachingResponseWrapper;
//
//import javax.servlet.FilterChain;
//import javax.servlet.ServletException;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.io.IOException;
//import java.nio.charset.StandardCharsets;
//import java.util.*;
//
///**
// * 请求/响应日志过滤器
// * 打印:traceId、method、uri、queryString、请求体、响应状态、耗时、响应体
// */
//@Slf4j
//@Component
//@Order(Ordered.HIGHEST_PRECEDENCE + 10)
//public class RequestResponseLoggingFilter extends OncePerRequestFilter {
//
//    @Autowired
//    private LogHeaderProperties logHeaderProperties;
//
//    /** 不打印 body 的路径前缀(健康检查、actuator 等) */
//    private static final Set<String> EXCLUDE_PATHS = new HashSet<>(Arrays.asList(
//            "/actuator", "/healthcheck", "/health", "/prometheus"
//    ));
//
//    /** 只对这些 Content-Type 打印 body(避免打印二进制流) */
//    private static final Set<String> LOGGABLE_CONTENT_TYPES = new HashSet<>(Arrays.asList(
//            MediaType.APPLICATION_JSON_VALUE,
//            MediaType.APPLICATION_JSON_UTF8_VALUE,
//            MediaType.TEXT_PLAIN_VALUE,
//            MediaType.TEXT_XML_VALUE,
//            MediaType.APPLICATION_XML_VALUE,
//            "application/x-www-form-urlencoded"
//    ));
//
//    private static final int MAX_BODY_LENGTH = 2000;
//
//    @Override
//    protected boolean shouldNotFilter(HttpServletRequest request) {
//        String uri = request.getRequestURI();
//        return EXCLUDE_PATHS.stream().anyMatch(uri::startsWith);
//    }
//
//    @Override
//    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
//                                    FilterChain chain) throws ServletException, IOException {
//        // 初始化 MDC(Filter 先于 Interceptor 执行,在此统一设置)
//        String traceId = request.getHeader("X-Trace-Id");
//        if (traceId == null || traceId.isEmpty()) {
//            traceId = UUID.randomUUID().toString().replace("-", "");
//        }
//        MDC.put("traceId",    traceId);
//        MDC.put("clientIp",   getClientIp(request));
//        MDC.put("requestUri", request.getRequestURI());
//        response.setHeader("X-Trace-Id", traceId);
//
//        ContentCachingRequestWrapper reqWrapper  = new ContentCachingRequestWrapper(request);
//        ContentCachingResponseWrapper respWrapper = new ContentCachingResponseWrapper(response);
//
//        long start = System.currentTimeMillis();
//        try {
//            chain.doFilter(reqWrapper, respWrapper);
//        } finally {
//            long cost = System.currentTimeMillis() - start;
//            logRequest(reqWrapper);
//            logResponse(respWrapper, cost);
//            // 必须把响应体写回,否则客户端收不到数据
//            respWrapper.copyBodyToResponse();
//            MDC.clear();
//        }
//    }
//
//    private String getClientIp(HttpServletRequest request) {
//        String ip = request.getHeader("X-Forwarded-For");
//        if (ip != null && !ip.isEmpty() && !"unknown".equalsIgnoreCase(ip)) {
//            return ip.split(",")[0].trim();
//        }
//        ip = request.getHeader("X-Real-IP");
//        if (ip != null && !ip.isEmpty() && !"unknown".equalsIgnoreCase(ip)) {
//            return ip;
//        }
//        return request.getRemoteAddr();
//    }
//
//    private void logRequest(ContentCachingRequestWrapper request) {
//        String traceId = MDC.get("traceId");
//        String uri     = request.getRequestURI();
//        String query   = request.getQueryString();
//        String method  = request.getMethod();
//        String body    = extractBody(request.getContentAsByteArray(), request.getContentType());
//
//        if (logHeaderProperties.isEnabled()) {
//            String headers = extractHeaders(request);
//            log.info(">>> [{}] {} {}{} | headers={} | body={}",
//                    traceId, method, uri,
//                    query != null ? "?" + query : "",
//                    headers, body);
//        } else {
//            log.info(">>> [{}] {} {}{} | body={}",
//                    traceId, method, uri,
//                    query != null ? "?" + query : "",
//                    body);
//        }
//    }
//
//    private String extractHeaders(HttpServletRequest request) {
//        List<String> names = logHeaderProperties.getNames();
//        StringBuilder sb = new StringBuilder("{");
//        boolean first = true;
//        if (names != null && !names.isEmpty()) {
//            // 只打印配置的请求头
//            for (String name : names) {
//                String value = request.getHeader(name);
//                if (value != null) {
//                    if (!first) sb.append(", ");
//                    first = false;
//                    sb.append(name).append("=").append(value);
//                }
//            }
//        } else {
//            // 未配置则打印全部请求头
//            Enumeration<String> headerNames = request.getHeaderNames();
//            while (headerNames != null && headerNames.hasMoreElements()) {
//                String name = headerNames.nextElement();
//                String value = request.getHeader(name);
//                if (!first) sb.append(", ");
//                first = false;
//                sb.append(name).append("=").append(value);
//            }
//        }
//        return sb.append("}").toString();
//    }
//
//    private void logResponse(ContentCachingResponseWrapper response, long cost) {
//        String traceId = MDC.get("traceId");
//        int    status  = response.getStatus();
//        String body    = extractBody(response.getContentAsByteArray(), response.getContentType());
//
//        log.info("<<< [{}] status={} cost={}ms | body={}",
//                traceId, status, cost, body);
//    }
//
//    private String extractBody(byte[] bodyBytes, String contentType) {
//        if (bodyBytes == null || bodyBytes.length == 0) {
//            return "";
//        }
//        if (!isLoggableContentType(contentType)) {
//            return "[binary, " + bodyBytes.length + " bytes]";
//        }
//        String body = new String(bodyBytes, StandardCharsets.UTF_8);
//        if (body.length() > MAX_BODY_LENGTH) {
//            body = body.substring(0, MAX_BODY_LENGTH) + "...(truncated)";
//        }
//        return body;
//    }
//
//    private boolean isLoggableContentType(String contentType) {
//        if (contentType == null) return true;
//        String ct = contentType.toLowerCase();
//        return LOGGABLE_CONTENT_TYPES.stream().anyMatch(ct::contains);
//    }
//}
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/constant/I18nKeyConstant.java
File was deleted
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/controller/HttpTestController.java
New file
@@ -0,0 +1,36 @@
package com.xiaopeng.trafficControl.controller;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.trafficControl.utils.MinistryOfTransport;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@RequestMapping("/")
public class HttpTestController {
    @Resource
    private MinistryOfTransport ministryOfTransport;
    /**
     * 测试上传数据接口
     * 用于验证上传数据的准确性
     * 模拟交通部接口
     */
    @ResponseBody
    @RequestMapping("/base/v0.1/testPush")
    public R<String> testPush(){
        try {
            String token = ministryOfTransport.getToken();
            return R.ok(token);
        }catch (Exception e){
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
    }
}
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/enums/SignatureType.java
File was deleted
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/util/HMACSHA1.java
File was deleted
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/util/HexUtil.java
File was deleted
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/util/ResourceUtil.java
File was deleted
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/util/SHA1Util.java
File was deleted
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/util/SignatureUtils.java
File was deleted
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/util/ThreadLocalSHA1.java
File was deleted
xp-robotaxi-traffic-control-boot/src/main/java/com/xiaopeng/trafficControl/utils/MinistryOfTransport.java
New file
@@ -0,0 +1,106 @@
package com.xiaopeng.trafficControl.utils;
import cn.hutool.core.io.FileUtil;
import cn.hutool.crypto.digest.MD5;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
 * 交通部接口对接
 */
@Slf4j
@Component
public class MinistryOfTransport {
    /**
     * 公司名称:广州易点智慧出行科技有限公司
     *
     * 平台简称:“有鹏出行”
     * 标识:XPQCB67N
     * key:gEhROt7lg4DEBanR
     *
     * 对接ip:127.0.0.1,125.71.236.64,47.98.173.145,116.62.136.48,39.108.249.22,47.105.208.135,47.112.126.81,114.55.179.11,39.170.77.50,120.26.242.215
     *
     * 接口地址:https://wycapi.jtj.gz.gov.cn/api/app/common/binapi
     */
    private final String companyId = "4401XPQCB67N";//公司标识
    private final String platform = "XPQC";
    private final String key = "gEhROt7lg4DEBanR";
    private final String url = "https://wycapi.jtj.gz.gov.cn/api/app/common/binapi";
    @Value("${xp.file.path}")
    private String filePath;
    /**
     * 获取token
     * @return
     */
    public String getToken(){
        //通过上传文件的方式获取token
        String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
        String fileName = platform + "_TOKEN_ACCESS_REQ_" + format + ".json";
        File file = FileUtil.file(filePath + fileName);
        if(!file.exists()){
            file.getParentFile().mkdirs();
            try {
                file.createNewFile();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            file.setReadable(true, false);//设置读取权限
            file.setWritable(true, false);//设置写入权限
        }
        JSONObject body = new JSONObject();
        JSONArray items = new JSONArray();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("platform", platform);
        jsonObject.put("key", key);
        items.add(jsonObject);
        body.put("items", items);
        log.info("获取token请求参数 {}", body.toJSONString());
        file = FileUtil.writeUtf8String(body.toJSONString(), file);
        String md5 = MD5.create().digestHex(file);
        HttpRequest post = HttpUtil.createPost(url);
        post.contentType("multipart/form-data;boundary=inputstream");
        post.header("binfile-md5", md5);
        post.header("binfile-gzip", "false");
        post.header("binfile-auth", "5cd4be8cf03842a6b4c3246011e3482e");
        post.form("binFile", file);
        post.form("filename", fileName);
        HttpResponse execute = post.execute();
        if(!execute.isOk()){
            log.info("获取token失败:{}", execute.body());
            return execute.body();
        }
        InputStream inputStream = execute.bodyStream();
        //读取inputStream流转成file文件
        File resultFile = FileUtil.file(filePath + "token_response_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS")) + ".json");
        resultFile.getParentFile().mkdirs();
        FileUtil.writeFromStream(inputStream, resultFile);
        String responseContent = FileUtil.readUtf8String(resultFile);
        log.info("获取token成功 {}", responseContent);
        return responseContent;
    }
}
xp-robotaxi-traffic-control-boot/src/main/resources/application-local.yml
New file
@@ -0,0 +1,114 @@
spring:
  config:
    activate:
      on-profile: local
  autoconfigure:
    exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
  redis:
    database: 99
    host: r-bp1ip8die60uuo3ovypd.redis.rds.aliyuncs.com
    password: syAktm2x9uDusoF_
    port: 6379
  data:
    mongodb:
      host: dds-bp1f4a38f3cccad4-pub.mongodb.rds.aliyuncs.com
      port: 3717
      database: xp_robotaxi
      username: xp_robotaxi
      password: hDXSBe_hs0d5KxUf
  shardingsphere:
    props:
      sql.show: true
      show-sql: true
    datasource:
      names: xp0
      xp0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://pc-bp1o444934f546768po.rwlb.rds.aliyuncs.com:3306/xp_rt_operation?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: xp_rt_operation
        password: g0Tw2f_KoNlmW21M
        druid:
          initial-size: 10
          min-idle: 10
          max-active: 100
          max-wait: 60000
          time-between-eviction-runs-millis: 60000
          min-evictable-idle-time-millis: 300000
          validation-query: SELECT 1
          test-while-idle: true
          test-on-borrow: false
          test-on-return: false
          pool-prepared-statements: true
          max-pool-prepared-statement-per-connection-size: 20
          filters: stat,wall,log4j
          connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
          remove-abandoned: true
          remove-abandoned-timeout: 1800
          log-abandoned: true
          stat-view-servlet:
            enabled: true
            url-pattern: /druid/*
            login-username: admin
            login-password: admin
            reset-enable: false
          wall:
            config:
              multi-statement-allow: false
    rules:
      sharding:
        tables:
          sys_oper_log:
            actual-data-nodes: xp0.sys_oper_log_${0..9}
            table-strategy:
              standard:
                sharding-column: userId
                sharding-algorithm-name: sys-oper-log-inline
            key-generate-strategy:
              column: oper_id
              key-generator-name: snowflake
          xp_agreement_app_user:
            actual-data-nodes: xp0.xp_agreement_app_user_${0..9}
            table-strategy:
              standard:
                sharding-column: app_user_id
                sharding-algorithm-name: xp-agreement-app-user-inline
            key-generate-strategy:
              column: id
              key-generator-name: snowflake
          xp_point:
            actual-data-nodes: xp0.xp_point_${0..9}
            table-strategy:
              standard:
                sharding-column: electronic_area_id
                sharding-algorithm-name: xp-point-inline
            key-generate-strategy:
              column: id
              key-generator-name: snowflake
        sharding-algorithms:
          sys-oper-log-inline:
            type: INLINE
            props:
              algorithm-expression: sys_oper_log_${userId % 10}
          xp-agreement-app-user-inline:
            type: INLINE
            props:
              algorithm-expression: xp_agreement_app_user_${app_user_id % 10}
          xp-point-inline:
            type: INLINE
            props:
              algorithm-expression: xp_point_${electronic_area_id % 10}
        key-generators:
          snowflake:
            type: SNOWFLAKE
# swagger配置
swagger:
  title: 合规监管接口文档
  enabled: true
  license: Powered By xiaopeng
  licenseUrl: http://127.0.0.1:5800/doc.html
seata:
  enabled: false
xp-robotaxi-traffic-control-boot/src/main/resources/bootstrap.yml
New file
@@ -0,0 +1,160 @@
server:
  port: 6110
  tomcat:
    basedir: /data/tomcat
# Spring
spring:
  application:
    # 应用名称
    name: xp-robotaxi-traffic-control-boot
  main:
    allow-bean-definition-overriding: true
    allow-circular-references: true
  profiles:
    # 环境配置
    active: dev
#    active: prod
---
spring:
  config:
    activate:
      on-profile: dev
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 192.168.110.80:8848
        service: ${spring.application.name}
        group: DEFAULT_GROUP
        namespace: 5185ac4b-6369-48eb-a21b-a7cbc441c5f1
        username: nacos
        password: nacos
      config:
        # 配置中心地址
        server-addr: 192.168.110.80:8848
        namespace: 5185ac4b-6369-48eb-a21b-a7cbc441c5f1
        group: DEFAULT_GROUP
        name: ${spring.application.name}
        username: nacos
        password: nacos
        # 配置文件格式
        file-extension: yml
        # 共享配置
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
---
seata:
  enabled: true
  application-id: ${spring.application.name}
  tx-service-group: seata_tx_group    #此处配置自定义的seata事务分组名称
  enable-auto-data-source-proxy: false    #关闭数据库代理
  service:
    vgroup-mapping:
      seata_tx_group: default
  data-source-proxy-mode: AT
  config:
    type: nacos
    nacos:
      # 开发环境
      server-addr: 192.168.110.80:8848
      namespace: 5185ac4b-6369-48eb-a21b-a7cbc441c5f1
      group: DEFAULT_GROUP
      data-id: seata-server.properties
      username: nacos
      password: nacos
      # 生产环境
  #      server-addr: 192.168.0.137:8848,192.168.0.123:8848
  #      namespace: c6cf40b5-44e8-43f9-be61-8d10fa830e2a
  #      group: DEFAULT_GROUP
  #      data-id: seata-server.properties
  #      username: nacos
  #      password: nacos
  registry:
    type: nacos
    nacos:
      application: seata-server
      # 开发环境
      server-addr: 192.168.110.80:8848
      namespace: 5185ac4b-6369-48eb-a21b-a7cbc441c5f1
      group: DEFAULT_GROUP
      username: nacos
      password: nacos
      # 生产环境
  #      server-addr: 192.168.0.137:8848,192.168.0.123:8848
  #      namespace: c6cf40b5-44e8-43f9-be61-8d10fa830e2a
  #      group: DEFAULT_GROUP
  #      username: nacos
  #      password: nacos
  cloud:
    nacos:
      discovery:
        # 开发环境
        server-addr: 192.168.110.80:8848
        namespace: 5185ac4b-6369-48eb-a21b-a7cbc441c5f1
        group: DEFAULT_GROUP
        application: seata-server #Nacos 中 Seata 名称
        username: nacos
        password: nacos
        # 生产环境
    #        server-addr: 192.168.0.137:8848,192.168.0.123:8848
    #        namespace: c6cf40b5-44e8-43f9-be61-8d10fa830e2a
    #        group: DEFAULT_GROUP
    #        application: seata-server #Nacos 中 Seata 名称
    #        username: nacos
    #        password: nacos
    sentinel:
      transport:
        dashboard: 192.168.0.137:8080  #  Sentinel控制台地址
      eager: true
---
spring:
  config:
    activate:
      on-profile: prod
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 192.168.0.137:8848,192.168.0.123:8848
        service: ${spring.application.name}
        group: DEFAULT_GROUP
        namespace: c6cf40b5-44e8-43f9-be61-8d10fa830e2a
        username: nacos
        password: nacos
      config:
        # 配置中心地址
        server-addr: 192.168.0.137:8848,192.168.0.123:8848
        namespace: c6cf40b5-44e8-43f9-be61-8d10fa830e2a
        username: nacos
        password: nacos
        group: DEFAULT_GROUP
        name: ${spring.application.name}
        # 配置文件格式
        file-extension: yml
        # 共享配置
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
---
spring:
  config:
    activate:
      on-profile: test
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 127.0.0.1:8848
        service: ${spring.application.name}
        group: DEFAULT_GROUP
        namespace: 96712c7a-480b-4f40-b783-39f00f3b33ce
      config:
        # 配置中心地址
        server-addr: 127.0.0.1:8848
        namespace: 96712c7a-480b-4f40-b783-39f00f3b33ce
        group: DEFAULT_GROUP
        name: ${spring.application.name}
        # 配置文件格式
        file-extension: yml
        # 共享配置
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
xp-robotaxi-traffic-control-boot/src/main/resources/logback.xml.bak
File was deleted
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java
@@ -770,7 +770,7 @@
    @PostMapping("/inner/vehicle/queryVehiclePositionByVin")
    public R<List<String>> queryVehiclePositionByVin(@RequestBody VehiclePositionByVinDto dto){
        List<XpVehicle> list = xpVehicleService.list(new LambdaQueryWrapper<XpVehicle>().eq(XpVehicle::getState, 0)
                .eq(XpVehicle::getOperatingStatus, 1).eq(XpVehicle::getElectronicId, dto.getFenceId()).in(XpVehicle::getVehicleVin,
                .eq(XpVehicle::getOperatingStatus, 1).eq(XpVehicle::getVehicleType,2).eq(XpVehicle::getElectronicId, dto.getFenceId()).in(XpVehicle::getVehicleVin,
                dto.getVinList()));
        if(list.isEmpty()){
            return R.ok(new ArrayList<>());