From ed838e62602c0a63a64ff4bd144a0d16cc9a7cf8 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期五, 10 四月 2026 09:39:25 +0800
Subject: [PATCH] 和客户同步1.0版本

---
 xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/impl/VehicleRtInfoServiceImpl.java |   58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 57 insertions(+), 1 deletions(-)

diff --git a/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/impl/VehicleRtInfoServiceImpl.java b/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/impl/VehicleRtInfoServiceImpl.java
index c8e08d6..5b9bf75 100644
--- a/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/impl/VehicleRtInfoServiceImpl.java
+++ b/xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/impl/VehicleRtInfoServiceImpl.java
@@ -1,6 +1,10 @@
 package com.xiaopeng.automaticPilot.service.impl;
 
+import com.xiaopeng.api.feignClient.account.XpOperationUserClient;
+import com.xiaopeng.api.feignClient.account.XpOperationsRoleClient;
 import com.xiaopeng.api.feignClient.operation.SmsClient;
+import com.xiaopeng.api.model.account.XpOperationsRole;
+import com.xiaopeng.api.model.account.XpOperationsUser;
 import com.xiaopeng.api.vo.operation.SmsVo;
 import com.xiaopeng.automaticPilot.dto.XpCommonResponse;
 import com.xiaopeng.automaticPilot.dto.RobotaxiSmsCodeRequest;
@@ -9,6 +13,7 @@
 import com.xiaopeng.api.dto.vehicleConvoy.UpdateVehicleStateDto;
 import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
 import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
+import com.xiaopeng.common.core.domain.R;
 import com.xiaopeng.common.core.utils.MsgUtil;
 import com.xiaopeng.common.core.utils.StringUtils;
 import com.xiaopeng.common.redis.service.RedisService;
@@ -17,6 +22,7 @@
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
 
 import javax.annotation.Resource;
 import java.util.Collections;
@@ -41,17 +47,35 @@
     @Resource
     private SmsClient smsClient;
 
+    @Resource
+    private XpOperationUserClient xpOperationUserClient;
+
+    @Resource
+    private XpOperationsRoleClient xpOperationsRoleClient;
+
     @Value("${robotaxi.sms.app-id:1476153389173952512}")
     private String smsAppId;
 
     @Value("#{'${robotaxi.sms.whitelist.mobiles:}'.split(',')}")
     private List<String> whitelistMobiles;
 
+    /**
+     * 安全员角色ID,未配置或为空则不做安全员角色校验
+     */
+    @Value("${robotaxi.sms.safety-officer-role-id:#{null}}")
+    private Long safetyOfficerRoleId;
+
     @Override
     public XpCommonResponse<?> getRobotaxiSmsCode(RobotaxiSmsCodeRequest request) {
         XpCommonResponse<?> paramCheckError = validateSmsCodeRequest(request);
         if (paramCheckError != null) {
             return paramCheckError;
+        }
+
+        // 校验用户是否为安全员角色
+        XpCommonResponse<?> roleCheckError = validateSafetyOfficerRole(request.getMobile());
+        if (roleCheckError != null) {
+            return roleCheckError;
         }
 
         XpCommonResponse<?> vehicleCheckError = validateVehicleReadyIfNeeded(request.getSmsType(), request.getVin());
@@ -98,7 +122,7 @@
         if (!isWhitelisted) {
             String cachedCode = redisService.getCacheObject(key);
             if (StringUtils.isEmpty(cachedCode)) {
-                return XpCommonResponse.fail(RobotaxiErrorEnum.GENERAL_ERROR);
+                return XpCommonResponse.fail(RobotaxiErrorEnum.VERIFY_CODE_ERROR);
             }
             if (!cachedCode.equals(request.getCode())) {
                 return XpCommonResponse.fail(RobotaxiErrorEnum.VERIFY_CODE_ERROR);
@@ -151,6 +175,38 @@
         return null;
     }
 
+    /**
+     * 校验手机号对应的运维人员是否拥有安全员角色。
+     * 若未配置 safetyOfficerRoleId 则跳过校验。
+     */
+    private XpCommonResponse<?> validateSafetyOfficerRole(String mobile) {
+        if (safetyOfficerRoleId == null) {
+            return null;
+        }
+        try {
+            R<XpOperationsUser> userResult = xpOperationUserClient.getByExactPhone(mobile);
+            if (userResult == null || userResult.getData() == null) {
+                log.warn("安全员角色校验失败:手机号 {} 未找到对应运维人员", mobile);
+                return XpCommonResponse.fail(RobotaxiErrorEnum.NOT_SAFETY_OFFICER);
+            }
+
+            R<List<XpOperationsRole>> roleRelResult = xpOperationsRoleClient.listByOperationUserId(userResult.getData().getId());
+            if (roleRelResult != null && !CollectionUtils.isEmpty(roleRelResult.getData())) {
+                for (XpOperationsRole operationsRole : roleRelResult.getData()) {
+                    if (safetyOfficerRoleId.equals(operationsRole.getRoleId())) {
+                        return null; // 校验通过
+                    }
+                }
+            }
+
+            log.warn("安全员角色校验失败:运维人员 {} 不具备安全员角色(roleId={})", userResult.getData().getId(), safetyOfficerRoleId);
+            return XpCommonResponse.fail(RobotaxiErrorEnum.NOT_SAFETY_OFFICER);
+        } catch (Exception e) {
+            log.error("安全员角色校验异常,mobile={}", mobile, e);
+            return XpCommonResponse.fail(RobotaxiErrorEnum.GENERAL_ERROR);
+        }
+    }
+
     private String buildSmsCodeKey(String smsType, String vin, String mobile) {
         return "ROBOTAXI_SMS_CODE:" + smsType + ":" + vin + ":" + mobile;
     }

--
Gitblit v1.7.1